aboutsummaryrefslogtreecommitdiffstats
path: root/drivers
diff options
context:
space:
mode:
Diffstat (limited to 'drivers')
-rw-r--r--drivers/atm/ambassador.c2
-rw-r--r--drivers/atm/atmtcp.c2
-rw-r--r--drivers/atm/eni.c2
-rw-r--r--drivers/atm/firestream.c2
-rw-r--r--drivers/atm/fore200e.c2
-rw-r--r--drivers/atm/he.c2
-rw-r--r--drivers/atm/horizon.c2
-rw-r--r--drivers/atm/idt77252.c8
-rw-r--r--drivers/atm/lanai.c2
-rw-r--r--drivers/atm/nicstar.c167
-rw-r--r--drivers/atm/nicstar.h16
-rw-r--r--drivers/atm/zatm.c10
-rw-r--r--drivers/block/aoe/aoenet.c2
-rw-r--r--drivers/block/viodasd.c2
-rw-r--r--drivers/bluetooth/bfusb.c16
-rw-r--r--drivers/bluetooth/bluecard_cs.c24
-rw-r--r--drivers/bluetooth/bpa10x.c17
-rw-r--r--drivers/bluetooth/bt3c_cs.c12
-rw-r--r--drivers/bluetooth/btuart_cs.c10
-rw-r--r--drivers/bluetooth/dtl1_cs.c10
-rw-r--r--drivers/bluetooth/hci_bcsp.c18
-rw-r--r--drivers/bluetooth/hci_h4.c4
-rw-r--r--drivers/bluetooth/hci_ldisc.c4
-rw-r--r--drivers/bluetooth/hci_usb.c23
-rw-r--r--drivers/bluetooth/hci_vhci.c386
-rw-r--r--drivers/bluetooth/hci_vhci.h50
-rw-r--r--drivers/cdrom/viocd.c2
-rw-r--r--drivers/char/drm/Kconfig16
-rw-r--r--drivers/char/drm/Makefile7
-rw-r--r--drivers/char/drm/drm.h8
-rw-r--r--drivers/char/drm/drmP.h137
-rw-r--r--drivers/char/drm/drm_agpsupport.c143
-rw-r--r--drivers/char/drm/drm_bufs.c647
-rw-r--r--drivers/char/drm/drm_context.c17
-rw-r--r--drivers/char/drm/drm_drv.c79
-rw-r--r--drivers/char/drm/drm_fops.c6
-rw-r--r--drivers/char/drm/drm_ioctl.c2
-rw-r--r--drivers/char/drm/drm_memory.c8
-rw-r--r--drivers/char/drm/drm_pci.c55
-rw-r--r--drivers/char/drm/drm_pciids.h79
-rw-r--r--drivers/char/drm/drm_proc.c17
-rw-r--r--drivers/char/drm/drm_scatter.c11
-rw-r--r--drivers/char/drm/drm_stub.c8
-rw-r--r--drivers/char/drm/drm_vm.c92
-rw-r--r--drivers/char/drm/ffb_drv.c5
-rw-r--r--drivers/char/drm/gamma_context.h492
-rw-r--r--drivers/char/drm/gamma_dma.c946
-rw-r--r--drivers/char/drm/gamma_drm.h90
-rw-r--r--drivers/char/drm/gamma_drv.c59
-rw-r--r--drivers/char/drm/gamma_drv.h147
-rw-r--r--drivers/char/drm/gamma_lists.h215
-rw-r--r--drivers/char/drm/gamma_lock.h140
-rw-r--r--drivers/char/drm/gamma_old_dma.h313
-rw-r--r--drivers/char/drm/i810_dma.c22
-rw-r--r--drivers/char/drm/i810_drv.c1
-rw-r--r--drivers/char/drm/i810_drv.h1
-rw-r--r--drivers/char/drm/i830_dma.c22
-rw-r--r--drivers/char/drm/i830_drv.c1
-rw-r--r--drivers/char/drm/i830_drv.h1
-rw-r--r--drivers/char/drm/i915_dma.c31
-rw-r--r--drivers/char/drm/i915_drv.c1
-rw-r--r--drivers/char/drm/i915_drv.h4
-rw-r--r--drivers/char/drm/mga_dma.c602
-rw-r--r--drivers/char/drm/mga_drm.h98
-rw-r--r--drivers/char/drm/mga_drv.c45
-rw-r--r--drivers/char/drm/mga_drv.h94
-rw-r--r--drivers/char/drm/mga_ioc32.c67
-rw-r--r--drivers/char/drm/mga_irq.c72
-rw-r--r--drivers/char/drm/mga_state.c158
-rw-r--r--drivers/char/drm/mga_warp.c141
-rw-r--r--drivers/char/drm/r128_cce.c6
-rw-r--r--drivers/char/drm/r128_drm.h2
-rw-r--r--drivers/char/drm/r300_cmdbuf.c801
-rw-r--r--drivers/char/drm/r300_reg.h1412
-rw-r--r--drivers/char/drm/radeon_cp.c35
-rw-r--r--drivers/char/drm/radeon_drm.h46
-rw-r--r--drivers/char/drm/radeon_drv.c1
-rw-r--r--drivers/char/drm/radeon_drv.h30
-rw-r--r--drivers/char/drm/radeon_state.c75
-rw-r--r--drivers/char/drm/savage_bci.c1096
-rw-r--r--drivers/char/drm/savage_drm.h209
-rw-r--r--drivers/char/drm/savage_drv.c112
-rw-r--r--drivers/char/drm/savage_drv.h579
-rw-r--r--drivers/char/drm/savage_state.c1146
-rw-r--r--drivers/char/hvc_vio.c2
-rw-r--r--drivers/char/hvcs.c2
-rw-r--r--drivers/char/mwave/mwavedd.c21
-rw-r--r--drivers/char/random.c34
-rw-r--r--drivers/char/snsc_event.c11
-rw-r--r--drivers/char/viotape.c2
-rw-r--r--drivers/ieee1394/ieee1394_core.c4
-rw-r--r--drivers/isdn/act2000/capi.c2
-rw-r--r--drivers/isdn/i4l/isdn_net.c1
-rw-r--r--drivers/isdn/i4l/isdn_ppp.c1
-rw-r--r--drivers/media/dvb/ttpci/Kconfig3
-rw-r--r--drivers/misc/Kconfig2
-rw-r--r--drivers/net/Kconfig32
-rw-r--r--drivers/net/Makefile2
-rw-r--r--drivers/net/bnx2.c229
-rw-r--r--drivers/net/bnx2.h10
-rw-r--r--drivers/net/bonding/bond_3ad.c11
-rw-r--r--drivers/net/bonding/bond_3ad.h2
-rw-r--r--drivers/net/bonding/bond_alb.c5
-rw-r--r--drivers/net/chelsio/Makefile11
-rw-r--r--drivers/net/chelsio/common.h314
-rw-r--r--drivers/net/chelsio/cphy.h148
-rw-r--r--drivers/net/chelsio/cpl5_cmd.h145
-rw-r--r--drivers/net/chelsio/cxgb2.c1256
-rw-r--r--drivers/net/chelsio/elmer0.h151
-rw-r--r--drivers/net/chelsio/espi.c346
-rw-r--r--drivers/net/chelsio/espi.h68
-rw-r--r--drivers/net/chelsio/gmac.h134
-rw-r--r--drivers/net/chelsio/mv88x201x.c252
-rw-r--r--drivers/net/chelsio/pm3393.c826
-rw-r--r--drivers/net/chelsio/regs.h468
-rw-r--r--drivers/net/chelsio/sge.c1684
-rw-r--r--drivers/net/chelsio/sge.h105
-rw-r--r--drivers/net/chelsio/subr.c812
-rw-r--r--drivers/net/chelsio/suni1x10gexp_regs.h213
-rw-r--r--drivers/net/e100.c241
-rw-r--r--drivers/net/hamradio/bpqether.c4
-rw-r--r--drivers/net/ibmveth.c2
-rw-r--r--drivers/net/iseries_veth.c871
-rw-r--r--drivers/net/iseries_veth.h46
-rw-r--r--drivers/net/ppp_generic.c1
-rw-r--r--drivers/net/pppoe.c6
-rw-r--r--drivers/net/rrunner.c3
-rw-r--r--drivers/net/s2io.h4
-rw-r--r--drivers/net/shaper.c50
-rw-r--r--drivers/net/sis190.c1843
-rw-r--r--drivers/net/tg3.c325
-rw-r--r--drivers/net/tg3.h10
-rw-r--r--drivers/net/tulip/Kconfig12
-rw-r--r--drivers/net/tulip/Makefile1
-rw-r--r--drivers/net/tulip/de2104x.c2
-rw-r--r--drivers/net/tulip/media.c36
-rw-r--r--drivers/net/tulip/timer.c1
-rw-r--r--drivers/net/tulip/tulip.h8
-rw-r--r--drivers/net/tulip/tulip_core.c35
-rw-r--r--drivers/net/tulip/uli526x.c1749
-rw-r--r--drivers/net/wan/hdlc_generic.c2
-rw-r--r--drivers/net/wan/lapbether.c2
-rw-r--r--drivers/net/wan/sdla_fr.c22
-rw-r--r--drivers/net/wan/syncppp.c2
-rw-r--r--drivers/net/wireless/Kconfig106
-rw-r--r--drivers/net/wireless/Makefile6
-rw-r--r--drivers/net/wireless/airo.c65
-rw-r--r--drivers/net/wireless/atmel.c62
-rw-r--r--drivers/net/wireless/hostap/Kconfig73
-rw-r--r--drivers/net/wireless/hostap/Makefile5
-rw-r--r--drivers/net/wireless/hostap/hostap.c1198
-rw-r--r--drivers/net/wireless/hostap/hostap.h57
-rw-r--r--drivers/net/wireless/hostap/hostap_80211.h96
-rw-r--r--drivers/net/wireless/hostap/hostap_80211_rx.c1091
-rw-r--r--drivers/net/wireless/hostap/hostap_80211_tx.c524
-rw-r--r--drivers/net/wireless/hostap/hostap_ap.c3288
-rw-r--r--drivers/net/wireless/hostap/hostap_ap.h261
-rw-r--r--drivers/net/wireless/hostap/hostap_common.h435
-rw-r--r--drivers/net/wireless/hostap/hostap_config.h55
-rw-r--r--drivers/net/wireless/hostap/hostap_cs.c1030
-rw-r--r--drivers/net/wireless/hostap/hostap_download.c766
-rw-r--r--drivers/net/wireless/hostap/hostap_hw.c3445
-rw-r--r--drivers/net/wireless/hostap/hostap_info.c499
-rw-r--r--drivers/net/wireless/hostap/hostap_ioctl.c4102
-rw-r--r--drivers/net/wireless/hostap/hostap_pci.c473
-rw-r--r--drivers/net/wireless/hostap/hostap_plx.c645
-rw-r--r--drivers/net/wireless/hostap/hostap_proc.c448
-rw-r--r--drivers/net/wireless/hostap/hostap_wlan.h1033
-rw-r--r--drivers/net/wireless/ieee802_11.h78
-rw-r--r--drivers/net/wireless/ipw2100.c8679
-rw-r--r--drivers/net/wireless/ipw2100.h1167
-rw-r--r--drivers/net/wireless/ipw2200.c7353
-rw-r--r--drivers/net/wireless/ipw2200.h1742
-rw-r--r--drivers/net/wireless/orinoco.c11
-rw-r--r--drivers/net/wireless/strip.c2
-rw-r--r--drivers/net/wireless/wavelan_cs.c26
-rw-r--r--drivers/net/wireless/wavelan_cs.h6
-rw-r--r--drivers/net/wireless/wavelan_cs.p.h17
-rw-r--r--drivers/net/wireless/wl3501.h4
-rw-r--r--drivers/net/wireless/wl3501_cs.c11
-rw-r--r--drivers/pci/rom.c24
-rw-r--r--drivers/pci/setup-bus.c2
-rw-r--r--drivers/scsi/ahci.c40
-rw-r--r--drivers/scsi/ata_piix.c58
-rw-r--r--drivers/scsi/ibmvscsi/ibmvscsi.c2
-rw-r--r--drivers/scsi/ibmvscsi/rpa_vscsi.c1
-rw-r--r--drivers/scsi/libata-core.c52
-rw-r--r--drivers/scsi/libata-scsi.c53
-rw-r--r--drivers/scsi/libata.h45
-rw-r--r--drivers/scsi/sata_nv.c38
-rw-r--r--drivers/scsi/sata_promise.c83
-rw-r--r--drivers/scsi/sata_promise.h31
-rw-r--r--drivers/scsi/sata_qstor.c31
-rw-r--r--drivers/scsi/sata_sil.c33
-rw-r--r--drivers/scsi/sata_sis.c33
-rw-r--r--drivers/scsi/sata_svw.c33
-rw-r--r--drivers/scsi/sata_sx4.c33
-rw-r--r--drivers/scsi/sata_uli.c33
-rw-r--r--drivers/scsi/sata_via.c62
-rw-r--r--drivers/scsi/sata_vsc.c26
-rw-r--r--drivers/serial/21285.c10
-rw-r--r--drivers/serial/8250.c89
-rw-r--r--drivers/serial/8250.h6
-rw-r--r--drivers/serial/Kconfig2
-rw-r--r--drivers/serial/amba-pl010.c8
-rw-r--r--drivers/serial/amba-pl011.c8
-rw-r--r--drivers/serial/au1x00_uart.c8
-rw-r--r--drivers/serial/clps711x.c10
-rw-r--r--drivers/serial/cpm_uart/cpm_uart_core.c8
-rw-r--r--drivers/serial/dz.c10
-rw-r--r--drivers/serial/icom.c12
-rw-r--r--drivers/serial/imx.c28
-rw-r--r--drivers/serial/ioc4_serial.c6
-rw-r--r--drivers/serial/ip22zilog.c4
-rw-r--r--drivers/serial/jsm/jsm_tty.c4
-rw-r--r--drivers/serial/m32r_sio.c8
-rw-r--r--drivers/serial/mpc52xx_uart.c8
-rw-r--r--drivers/serial/mpsc.c8
-rw-r--r--drivers/serial/mux.c10
-rw-r--r--drivers/serial/pmac_zilog.c7
-rw-r--r--drivers/serial/pxa.c8
-rw-r--r--drivers/serial/s3c2410.c10
-rw-r--r--drivers/serial/sa1100.c8
-rw-r--r--drivers/serial/serial_core.c144
-rw-r--r--drivers/serial/serial_lh7a40x.c5
-rw-r--r--drivers/serial/serial_txx9.c8
-rw-r--r--drivers/serial/sh-sci.c12
-rw-r--r--drivers/serial/sn_console.c8
-rw-r--r--drivers/serial/sunsab.c8
-rw-r--r--drivers/serial/sunsu.c32
-rw-r--r--drivers/serial/sunzilog.c4
-rw-r--r--drivers/serial/uart00.c8
-rw-r--r--drivers/serial/v850e_uart.c6
-rw-r--r--drivers/serial/vr41xx_siu.c8
-rw-r--r--drivers/usb/net/Makefile2
-rw-r--r--drivers/usb/net/usbnet.c21
-rw-r--r--drivers/usb/net/zd1201.c16
-rw-r--r--drivers/w1/w1_int.c6
-rw-r--r--drivers/w1/w1_netlink.c2
239 files changed, 58954 insertions, 5222 deletions
diff --git a/drivers/atm/ambassador.c b/drivers/atm/ambassador.c
index 73c6b85299c1..d74a7c5e75dd 100644
--- a/drivers/atm/ambassador.c
+++ b/drivers/atm/ambassador.c
@@ -513,7 +513,7 @@ static void rx_complete (amb_dev * dev, rx_out * rx) {
513 513
514 // VC layer stats 514 // VC layer stats
515 atomic_inc(&atm_vcc->stats->rx); 515 atomic_inc(&atm_vcc->stats->rx);
516 do_gettimeofday(&skb->stamp); 516 __net_timestamp(skb);
517 // end of our responsability 517 // end of our responsability
518 atm_vcc->push (atm_vcc, skb); 518 atm_vcc->push (atm_vcc, skb);
519 return; 519 return;
diff --git a/drivers/atm/atmtcp.c b/drivers/atm/atmtcp.c
index f2f01cb82cb4..57f1810fdccd 100644
--- a/drivers/atm/atmtcp.c
+++ b/drivers/atm/atmtcp.c
@@ -325,7 +325,7 @@ static int atmtcp_c_send(struct atm_vcc *vcc,struct sk_buff *skb)
325 result = -ENOBUFS; 325 result = -ENOBUFS;
326 goto done; 326 goto done;
327 } 327 }
328 do_gettimeofday(&new_skb->stamp); 328 __net_timestamp(new_skb);
329 memcpy(skb_put(new_skb,skb->len),skb->data,skb->len); 329 memcpy(skb_put(new_skb,skb->len),skb->data,skb->len);
330 out_vcc->push(out_vcc,new_skb); 330 out_vcc->push(out_vcc,new_skb);
331 atomic_inc(&vcc->stats->tx); 331 atomic_inc(&vcc->stats->tx);
diff --git a/drivers/atm/eni.c b/drivers/atm/eni.c
index 10da36934769..c13c4d736ef5 100644
--- a/drivers/atm/eni.c
+++ b/drivers/atm/eni.c
@@ -537,7 +537,7 @@ static int rx_aal0(struct atm_vcc *vcc)
537 return 0; 537 return 0;
538 } 538 }
539 skb_put(skb,length); 539 skb_put(skb,length);
540 skb->stamp = eni_vcc->timestamp; 540 skb_set_timestamp(skb, &eni_vcc->timestamp);
541 DPRINTK("got len %ld\n",length); 541 DPRINTK("got len %ld\n",length);
542 if (do_rx_dma(vcc,skb,1,length >> 2,length >> 2)) return 1; 542 if (do_rx_dma(vcc,skb,1,length >> 2,length >> 2)) return 1;
543 eni_vcc->rxing++; 543 eni_vcc->rxing++;
diff --git a/drivers/atm/firestream.c b/drivers/atm/firestream.c
index b078fa548ebf..58219744f5db 100644
--- a/drivers/atm/firestream.c
+++ b/drivers/atm/firestream.c
@@ -815,7 +815,7 @@ static void process_incoming (struct fs_dev *dev, struct queue *q)
815 skb_put (skb, qe->p1 & 0xffff); 815 skb_put (skb, qe->p1 & 0xffff);
816 ATM_SKB(skb)->vcc = atm_vcc; 816 ATM_SKB(skb)->vcc = atm_vcc;
817 atomic_inc(&atm_vcc->stats->rx); 817 atomic_inc(&atm_vcc->stats->rx);
818 do_gettimeofday(&skb->stamp); 818 __net_timestamp(skb);
819 fs_dprintk (FS_DEBUG_ALLOC, "Free rec-skb: %p (pushed)\n", skb); 819 fs_dprintk (FS_DEBUG_ALLOC, "Free rec-skb: %p (pushed)\n", skb);
820 atm_vcc->push (atm_vcc, skb); 820 atm_vcc->push (atm_vcc, skb);
821 fs_dprintk (FS_DEBUG_ALLOC, "Free rec-d: %p\n", pe); 821 fs_dprintk (FS_DEBUG_ALLOC, "Free rec-d: %p\n", pe);
diff --git a/drivers/atm/fore200e.c b/drivers/atm/fore200e.c
index 5f702199543a..2bf723a7b6e6 100644
--- a/drivers/atm/fore200e.c
+++ b/drivers/atm/fore200e.c
@@ -1176,7 +1176,7 @@ fore200e_push_rpd(struct fore200e* fore200e, struct atm_vcc* vcc, struct rpd* rp
1176 return -ENOMEM; 1176 return -ENOMEM;
1177 } 1177 }
1178 1178
1179 do_gettimeofday(&skb->stamp); 1179 __net_timestamp(skb);
1180 1180
1181#ifdef FORE200E_52BYTE_AAL0_SDU 1181#ifdef FORE200E_52BYTE_AAL0_SDU
1182 if (cell_header) { 1182 if (cell_header) {
diff --git a/drivers/atm/he.c b/drivers/atm/he.c
index 28250c9b32d6..fde9334059af 100644
--- a/drivers/atm/he.c
+++ b/drivers/atm/he.c
@@ -1886,7 +1886,7 @@ he_service_rbrq(struct he_dev *he_dev, int group)
1886 if (rx_skb_reserve > 0) 1886 if (rx_skb_reserve > 0)
1887 skb_reserve(skb, rx_skb_reserve); 1887 skb_reserve(skb, rx_skb_reserve);
1888 1888
1889 do_gettimeofday(&skb->stamp); 1889 __net_timestamp(skb);
1890 1890
1891 for (iov = he_vcc->iov_head; 1891 for (iov = he_vcc->iov_head;
1892 iov < he_vcc->iov_tail; ++iov) { 1892 iov < he_vcc->iov_tail; ++iov) {
diff --git a/drivers/atm/horizon.c b/drivers/atm/horizon.c
index 924a2c8988bd..0cded0468003 100644
--- a/drivers/atm/horizon.c
+++ b/drivers/atm/horizon.c
@@ -1034,7 +1034,7 @@ static void rx_schedule (hrz_dev * dev, int irq) {
1034 struct atm_vcc * vcc = ATM_SKB(skb)->vcc; 1034 struct atm_vcc * vcc = ATM_SKB(skb)->vcc;
1035 // VC layer stats 1035 // VC layer stats
1036 atomic_inc(&vcc->stats->rx); 1036 atomic_inc(&vcc->stats->rx);
1037 do_gettimeofday(&skb->stamp); 1037 __net_timestamp(skb);
1038 // end of our responsability 1038 // end of our responsability
1039 vcc->push (vcc, skb); 1039 vcc->push (vcc, skb);
1040 } 1040 }
diff --git a/drivers/atm/idt77252.c b/drivers/atm/idt77252.c
index 30b7e990ed0b..b4a76cade646 100644
--- a/drivers/atm/idt77252.c
+++ b/drivers/atm/idt77252.c
@@ -1101,7 +1101,7 @@ dequeue_rx(struct idt77252_dev *card, struct rsq_entry *rsqe)
1101 cell, ATM_CELL_PAYLOAD); 1101 cell, ATM_CELL_PAYLOAD);
1102 1102
1103 ATM_SKB(sb)->vcc = vcc; 1103 ATM_SKB(sb)->vcc = vcc;
1104 do_gettimeofday(&sb->stamp); 1104 __net_timestamp(sb);
1105 vcc->push(vcc, sb); 1105 vcc->push(vcc, sb);
1106 atomic_inc(&vcc->stats->rx); 1106 atomic_inc(&vcc->stats->rx);
1107 1107
@@ -1179,7 +1179,7 @@ dequeue_rx(struct idt77252_dev *card, struct rsq_entry *rsqe)
1179 1179
1180 skb_trim(skb, len); 1180 skb_trim(skb, len);
1181 ATM_SKB(skb)->vcc = vcc; 1181 ATM_SKB(skb)->vcc = vcc;
1182 do_gettimeofday(&skb->stamp); 1182 __net_timestamp(skb);
1183 1183
1184 vcc->push(vcc, skb); 1184 vcc->push(vcc, skb);
1185 atomic_inc(&vcc->stats->rx); 1185 atomic_inc(&vcc->stats->rx);
@@ -1201,7 +1201,7 @@ dequeue_rx(struct idt77252_dev *card, struct rsq_entry *rsqe)
1201 1201
1202 skb_trim(skb, len); 1202 skb_trim(skb, len);
1203 ATM_SKB(skb)->vcc = vcc; 1203 ATM_SKB(skb)->vcc = vcc;
1204 do_gettimeofday(&skb->stamp); 1204 __net_timestamp(skb);
1205 1205
1206 vcc->push(vcc, skb); 1206 vcc->push(vcc, skb);
1207 atomic_inc(&vcc->stats->rx); 1207 atomic_inc(&vcc->stats->rx);
@@ -1340,7 +1340,7 @@ idt77252_rx_raw(struct idt77252_dev *card)
1340 ATM_CELL_PAYLOAD); 1340 ATM_CELL_PAYLOAD);
1341 1341
1342 ATM_SKB(sb)->vcc = vcc; 1342 ATM_SKB(sb)->vcc = vcc;
1343 do_gettimeofday(&sb->stamp); 1343 __net_timestamp(sb);
1344 vcc->push(vcc, sb); 1344 vcc->push(vcc, sb);
1345 atomic_inc(&vcc->stats->rx); 1345 atomic_inc(&vcc->stats->rx);
1346 1346
diff --git a/drivers/atm/lanai.c b/drivers/atm/lanai.c
index ffe3afa723b8..51ec14787293 100644
--- a/drivers/atm/lanai.c
+++ b/drivers/atm/lanai.c
@@ -1427,7 +1427,7 @@ static void vcc_rx_aal5(struct lanai_vcc *lvcc, int endptr)
1427 skb_put(skb, size); 1427 skb_put(skb, size);
1428 vcc_rx_memcpy(skb->data, lvcc, size); 1428 vcc_rx_memcpy(skb->data, lvcc, size);
1429 ATM_SKB(skb)->vcc = lvcc->rx.atmvcc; 1429 ATM_SKB(skb)->vcc = lvcc->rx.atmvcc;
1430 do_gettimeofday(&skb->stamp); 1430 __net_timestamp(skb);
1431 lvcc->rx.atmvcc->push(lvcc->rx.atmvcc, skb); 1431 lvcc->rx.atmvcc->push(lvcc->rx.atmvcc, skb);
1432 atomic_inc(&lvcc->rx.atmvcc->stats->rx); 1432 atomic_inc(&lvcc->rx.atmvcc->stats->rx);
1433 out: 1433 out:
diff --git a/drivers/atm/nicstar.c b/drivers/atm/nicstar.c
index b2a7b754fd14..c57e20dcb0f8 100644
--- a/drivers/atm/nicstar.c
+++ b/drivers/atm/nicstar.c
@@ -214,8 +214,7 @@ static int __devinit ns_init_card(int i, struct pci_dev *pcidev);
214static void __devinit ns_init_card_error(ns_dev *card, int error); 214static void __devinit ns_init_card_error(ns_dev *card, int error);
215static scq_info *get_scq(int size, u32 scd); 215static scq_info *get_scq(int size, u32 scd);
216static void free_scq(scq_info *scq, struct atm_vcc *vcc); 216static void free_scq(scq_info *scq, struct atm_vcc *vcc);
217static void push_rxbufs(ns_dev *card, u32 type, u32 handle1, u32 addr1, 217static void push_rxbufs(ns_dev *, struct sk_buff *);
218 u32 handle2, u32 addr2);
219static irqreturn_t ns_irq_handler(int irq, void *dev_id, struct pt_regs *regs); 218static irqreturn_t ns_irq_handler(int irq, void *dev_id, struct pt_regs *regs);
220static int ns_open(struct atm_vcc *vcc); 219static int ns_open(struct atm_vcc *vcc);
221static void ns_close(struct atm_vcc *vcc); 220static void ns_close(struct atm_vcc *vcc);
@@ -766,6 +765,7 @@ static int __devinit ns_init_card(int i, struct pci_dev *pcidev)
766 ns_init_card_error(card, error); 765 ns_init_card_error(card, error);
767 return error; 766 return error;
768 } 767 }
768 NS_SKB_CB(hb)->buf_type = BUF_NONE;
769 skb_queue_tail(&card->hbpool.queue, hb); 769 skb_queue_tail(&card->hbpool.queue, hb);
770 card->hbpool.count++; 770 card->hbpool.count++;
771 } 771 }
@@ -786,9 +786,10 @@ static int __devinit ns_init_card(int i, struct pci_dev *pcidev)
786 ns_init_card_error(card, error); 786 ns_init_card_error(card, error);
787 return error; 787 return error;
788 } 788 }
789 NS_SKB_CB(lb)->buf_type = BUF_LG;
789 skb_queue_tail(&card->lbpool.queue, lb); 790 skb_queue_tail(&card->lbpool.queue, lb);
790 skb_reserve(lb, NS_SMBUFSIZE); 791 skb_reserve(lb, NS_SMBUFSIZE);
791 push_rxbufs(card, BUF_LG, (u32) lb, (u32) virt_to_bus(lb->data), 0, 0); 792 push_rxbufs(card, lb);
792 /* Due to the implementation of push_rxbufs() this is 1, not 0 */ 793 /* Due to the implementation of push_rxbufs() this is 1, not 0 */
793 if (j == 1) 794 if (j == 1)
794 { 795 {
@@ -822,9 +823,10 @@ static int __devinit ns_init_card(int i, struct pci_dev *pcidev)
822 ns_init_card_error(card, error); 823 ns_init_card_error(card, error);
823 return error; 824 return error;
824 } 825 }
826 NS_SKB_CB(sb)->buf_type = BUF_SM;
825 skb_queue_tail(&card->sbpool.queue, sb); 827 skb_queue_tail(&card->sbpool.queue, sb);
826 skb_reserve(sb, NS_AAL0_HEADER); 828 skb_reserve(sb, NS_AAL0_HEADER);
827 push_rxbufs(card, BUF_SM, (u32) sb, (u32) virt_to_bus(sb->data), 0, 0); 829 push_rxbufs(card, sb);
828 } 830 }
829 /* Test for strange behaviour which leads to crashes */ 831 /* Test for strange behaviour which leads to crashes */
830 if ((bcount = ns_stat_sfbqc_get(readl(card->membase + STAT))) < card->sbnr.min) 832 if ((bcount = ns_stat_sfbqc_get(readl(card->membase + STAT))) < card->sbnr.min)
@@ -852,6 +854,7 @@ static int __devinit ns_init_card(int i, struct pci_dev *pcidev)
852 ns_init_card_error(card, error); 854 ns_init_card_error(card, error);
853 return error; 855 return error;
854 } 856 }
857 NS_SKB_CB(iovb)->buf_type = BUF_NONE;
855 skb_queue_tail(&card->iovpool.queue, iovb); 858 skb_queue_tail(&card->iovpool.queue, iovb);
856 card->iovpool.count++; 859 card->iovpool.count++;
857 } 860 }
@@ -1078,12 +1081,18 @@ static void free_scq(scq_info *scq, struct atm_vcc *vcc)
1078 1081
1079/* The handles passed must be pointers to the sk_buff containing the small 1082/* The handles passed must be pointers to the sk_buff containing the small
1080 or large buffer(s) cast to u32. */ 1083 or large buffer(s) cast to u32. */
1081static void push_rxbufs(ns_dev *card, u32 type, u32 handle1, u32 addr1, 1084static void push_rxbufs(ns_dev *card, struct sk_buff *skb)
1082 u32 handle2, u32 addr2)
1083{ 1085{
1086 struct ns_skb_cb *cb = NS_SKB_CB(skb);
1087 u32 handle1, addr1;
1088 u32 handle2, addr2;
1084 u32 stat; 1089 u32 stat;
1085 unsigned long flags; 1090 unsigned long flags;
1086 1091
1092 /* *BARF* */
1093 handle2 = addr2 = 0;
1094 handle1 = (u32)skb;
1095 addr1 = (u32)virt_to_bus(skb->data);
1087 1096
1088#ifdef GENERAL_DEBUG 1097#ifdef GENERAL_DEBUG
1089 if (!addr1) 1098 if (!addr1)
@@ -1093,7 +1102,7 @@ static void push_rxbufs(ns_dev *card, u32 type, u32 handle1, u32 addr1,
1093 stat = readl(card->membase + STAT); 1102 stat = readl(card->membase + STAT);
1094 card->sbfqc = ns_stat_sfbqc_get(stat); 1103 card->sbfqc = ns_stat_sfbqc_get(stat);
1095 card->lbfqc = ns_stat_lfbqc_get(stat); 1104 card->lbfqc = ns_stat_lfbqc_get(stat);
1096 if (type == BUF_SM) 1105 if (cb->buf_type == BUF_SM)
1097 { 1106 {
1098 if (!addr2) 1107 if (!addr2)
1099 { 1108 {
@@ -1111,7 +1120,7 @@ static void push_rxbufs(ns_dev *card, u32 type, u32 handle1, u32 addr1,
1111 } 1120 }
1112 } 1121 }
1113 } 1122 }
1114 else /* type == BUF_LG */ 1123 else /* buf_type == BUF_LG */
1115 { 1124 {
1116 if (!addr2) 1125 if (!addr2)
1117 { 1126 {
@@ -1132,26 +1141,26 @@ static void push_rxbufs(ns_dev *card, u32 type, u32 handle1, u32 addr1,
1132 1141
1133 if (addr2) 1142 if (addr2)
1134 { 1143 {
1135 if (type == BUF_SM) 1144 if (cb->buf_type == BUF_SM)
1136 { 1145 {
1137 if (card->sbfqc >= card->sbnr.max) 1146 if (card->sbfqc >= card->sbnr.max)
1138 { 1147 {
1139 skb_unlink((struct sk_buff *) handle1); 1148 skb_unlink((struct sk_buff *) handle1, &card->sbpool.queue);
1140 dev_kfree_skb_any((struct sk_buff *) handle1); 1149 dev_kfree_skb_any((struct sk_buff *) handle1);
1141 skb_unlink((struct sk_buff *) handle2); 1150 skb_unlink((struct sk_buff *) handle2, &card->sbpool.queue);
1142 dev_kfree_skb_any((struct sk_buff *) handle2); 1151 dev_kfree_skb_any((struct sk_buff *) handle2);
1143 return; 1152 return;
1144 } 1153 }
1145 else 1154 else
1146 card->sbfqc += 2; 1155 card->sbfqc += 2;
1147 } 1156 }
1148 else /* (type == BUF_LG) */ 1157 else /* (buf_type == BUF_LG) */
1149 { 1158 {
1150 if (card->lbfqc >= card->lbnr.max) 1159 if (card->lbfqc >= card->lbnr.max)
1151 { 1160 {
1152 skb_unlink((struct sk_buff *) handle1); 1161 skb_unlink((struct sk_buff *) handle1, &card->lbpool.queue);
1153 dev_kfree_skb_any((struct sk_buff *) handle1); 1162 dev_kfree_skb_any((struct sk_buff *) handle1);
1154 skb_unlink((struct sk_buff *) handle2); 1163 skb_unlink((struct sk_buff *) handle2, &card->lbpool.queue);
1155 dev_kfree_skb_any((struct sk_buff *) handle2); 1164 dev_kfree_skb_any((struct sk_buff *) handle2);
1156 return; 1165 return;
1157 } 1166 }
@@ -1166,12 +1175,12 @@ static void push_rxbufs(ns_dev *card, u32 type, u32 handle1, u32 addr1,
1166 writel(handle2, card->membase + DR2); 1175 writel(handle2, card->membase + DR2);
1167 writel(addr1, card->membase + DR1); 1176 writel(addr1, card->membase + DR1);
1168 writel(handle1, card->membase + DR0); 1177 writel(handle1, card->membase + DR0);
1169 writel(NS_CMD_WRITE_FREEBUFQ | (u32) type, card->membase + CMD); 1178 writel(NS_CMD_WRITE_FREEBUFQ | cb->buf_type, card->membase + CMD);
1170 1179
1171 spin_unlock_irqrestore(&card->res_lock, flags); 1180 spin_unlock_irqrestore(&card->res_lock, flags);
1172 1181
1173 XPRINTK("nicstar%d: Pushing %s buffers at 0x%x and 0x%x.\n", card->index, 1182 XPRINTK("nicstar%d: Pushing %s buffers at 0x%x and 0x%x.\n", card->index,
1174 (type == BUF_SM ? "small" : "large"), addr1, addr2); 1183 (cb->buf_type == BUF_SM ? "small" : "large"), addr1, addr2);
1175 } 1184 }
1176 1185
1177 if (!card->efbie && card->sbfqc >= card->sbnr.min && 1186 if (!card->efbie && card->sbfqc >= card->sbnr.min &&
@@ -1322,9 +1331,10 @@ static irqreturn_t ns_irq_handler(int irq, void *dev_id, struct pt_regs *regs)
1322 card->efbie = 0; 1331 card->efbie = 0;
1323 break; 1332 break;
1324 } 1333 }
1334 NS_SKB_CB(sb)->buf_type = BUF_SM;
1325 skb_queue_tail(&card->sbpool.queue, sb); 1335 skb_queue_tail(&card->sbpool.queue, sb);
1326 skb_reserve(sb, NS_AAL0_HEADER); 1336 skb_reserve(sb, NS_AAL0_HEADER);
1327 push_rxbufs(card, BUF_SM, (u32) sb, (u32) virt_to_bus(sb->data), 0, 0); 1337 push_rxbufs(card, sb);
1328 } 1338 }
1329 card->sbfqc = i; 1339 card->sbfqc = i;
1330 process_rsq(card); 1340 process_rsq(card);
@@ -1348,9 +1358,10 @@ static irqreturn_t ns_irq_handler(int irq, void *dev_id, struct pt_regs *regs)
1348 card->efbie = 0; 1358 card->efbie = 0;
1349 break; 1359 break;
1350 } 1360 }
1361 NS_SKB_CB(lb)->buf_type = BUF_LG;
1351 skb_queue_tail(&card->lbpool.queue, lb); 1362 skb_queue_tail(&card->lbpool.queue, lb);
1352 skb_reserve(lb, NS_SMBUFSIZE); 1363 skb_reserve(lb, NS_SMBUFSIZE);
1353 push_rxbufs(card, BUF_LG, (u32) lb, (u32) virt_to_bus(lb->data), 0, 0); 1364 push_rxbufs(card, lb);
1354 } 1365 }
1355 card->lbfqc = i; 1366 card->lbfqc = i;
1356 process_rsq(card); 1367 process_rsq(card);
@@ -2202,7 +2213,7 @@ static void dequeue_rx(ns_dev *card, ns_rsqe *rsqe)
2202 memcpy(sb->tail, cell, ATM_CELL_PAYLOAD); 2213 memcpy(sb->tail, cell, ATM_CELL_PAYLOAD);
2203 skb_put(sb, ATM_CELL_PAYLOAD); 2214 skb_put(sb, ATM_CELL_PAYLOAD);
2204 ATM_SKB(sb)->vcc = vcc; 2215 ATM_SKB(sb)->vcc = vcc;
2205 do_gettimeofday(&sb->stamp); 2216 __net_timestamp(sb);
2206 vcc->push(vcc, sb); 2217 vcc->push(vcc, sb);
2207 atomic_inc(&vcc->stats->rx); 2218 atomic_inc(&vcc->stats->rx);
2208 cell += ATM_CELL_PAYLOAD; 2219 cell += ATM_CELL_PAYLOAD;
@@ -2227,6 +2238,7 @@ static void dequeue_rx(ns_dev *card, ns_rsqe *rsqe)
2227 recycle_rx_buf(card, skb); 2238 recycle_rx_buf(card, skb);
2228 return; 2239 return;
2229 } 2240 }
2241 NS_SKB_CB(iovb)->buf_type = BUF_NONE;
2230 } 2242 }
2231 else 2243 else
2232 if (--card->iovpool.count < card->iovnr.min) 2244 if (--card->iovpool.count < card->iovnr.min)
@@ -2234,6 +2246,7 @@ static void dequeue_rx(ns_dev *card, ns_rsqe *rsqe)
2234 struct sk_buff *new_iovb; 2246 struct sk_buff *new_iovb;
2235 if ((new_iovb = alloc_skb(NS_IOVBUFSIZE, GFP_ATOMIC)) != NULL) 2247 if ((new_iovb = alloc_skb(NS_IOVBUFSIZE, GFP_ATOMIC)) != NULL)
2236 { 2248 {
2249 NS_SKB_CB(iovb)->buf_type = BUF_NONE;
2237 skb_queue_tail(&card->iovpool.queue, new_iovb); 2250 skb_queue_tail(&card->iovpool.queue, new_iovb);
2238 card->iovpool.count++; 2251 card->iovpool.count++;
2239 } 2252 }
@@ -2264,7 +2277,7 @@ static void dequeue_rx(ns_dev *card, ns_rsqe *rsqe)
2264 2277
2265 if (NS_SKB(iovb)->iovcnt == 1) 2278 if (NS_SKB(iovb)->iovcnt == 1)
2266 { 2279 {
2267 if (skb->list != &card->sbpool.queue) 2280 if (NS_SKB_CB(skb)->buf_type != BUF_SM)
2268 { 2281 {
2269 printk("nicstar%d: Expected a small buffer, and this is not one.\n", 2282 printk("nicstar%d: Expected a small buffer, and this is not one.\n",
2270 card->index); 2283 card->index);
@@ -2278,7 +2291,7 @@ static void dequeue_rx(ns_dev *card, ns_rsqe *rsqe)
2278 } 2291 }
2279 else /* NS_SKB(iovb)->iovcnt >= 2 */ 2292 else /* NS_SKB(iovb)->iovcnt >= 2 */
2280 { 2293 {
2281 if (skb->list != &card->lbpool.queue) 2294 if (NS_SKB_CB(skb)->buf_type != BUF_LG)
2282 { 2295 {
2283 printk("nicstar%d: Expected a large buffer, and this is not one.\n", 2296 printk("nicstar%d: Expected a large buffer, and this is not one.\n",
2284 card->index); 2297 card->index);
@@ -2322,8 +2335,7 @@ static void dequeue_rx(ns_dev *card, ns_rsqe *rsqe)
2322 /* skb points to a small buffer */ 2335 /* skb points to a small buffer */
2323 if (!atm_charge(vcc, skb->truesize)) 2336 if (!atm_charge(vcc, skb->truesize))
2324 { 2337 {
2325 push_rxbufs(card, BUF_SM, (u32) skb, (u32) virt_to_bus(skb->data), 2338 push_rxbufs(card, skb);
2326 0, 0);
2327 atomic_inc(&vcc->stats->rx_drop); 2339 atomic_inc(&vcc->stats->rx_drop);
2328 } 2340 }
2329 else 2341 else
@@ -2334,7 +2346,7 @@ static void dequeue_rx(ns_dev *card, ns_rsqe *rsqe)
2334 skb->destructor = ns_sb_destructor; 2346 skb->destructor = ns_sb_destructor;
2335#endif /* NS_USE_DESTRUCTORS */ 2347#endif /* NS_USE_DESTRUCTORS */
2336 ATM_SKB(skb)->vcc = vcc; 2348 ATM_SKB(skb)->vcc = vcc;
2337 do_gettimeofday(&skb->stamp); 2349 __net_timestamp(skb);
2338 vcc->push(vcc, skb); 2350 vcc->push(vcc, skb);
2339 atomic_inc(&vcc->stats->rx); 2351 atomic_inc(&vcc->stats->rx);
2340 } 2352 }
@@ -2350,8 +2362,7 @@ static void dequeue_rx(ns_dev *card, ns_rsqe *rsqe)
2350 { 2362 {
2351 if (!atm_charge(vcc, sb->truesize)) 2363 if (!atm_charge(vcc, sb->truesize))
2352 { 2364 {
2353 push_rxbufs(card, BUF_SM, (u32) sb, (u32) virt_to_bus(sb->data), 2365 push_rxbufs(card, sb);
2354 0, 0);
2355 atomic_inc(&vcc->stats->rx_drop); 2366 atomic_inc(&vcc->stats->rx_drop);
2356 } 2367 }
2357 else 2368 else
@@ -2362,21 +2373,19 @@ static void dequeue_rx(ns_dev *card, ns_rsqe *rsqe)
2362 sb->destructor = ns_sb_destructor; 2373 sb->destructor = ns_sb_destructor;
2363#endif /* NS_USE_DESTRUCTORS */ 2374#endif /* NS_USE_DESTRUCTORS */
2364 ATM_SKB(sb)->vcc = vcc; 2375 ATM_SKB(sb)->vcc = vcc;
2365 do_gettimeofday(&sb->stamp); 2376 __net_timestamp(sb);
2366 vcc->push(vcc, sb); 2377 vcc->push(vcc, sb);
2367 atomic_inc(&vcc->stats->rx); 2378 atomic_inc(&vcc->stats->rx);
2368 } 2379 }
2369 2380
2370 push_rxbufs(card, BUF_LG, (u32) skb, 2381 push_rxbufs(card, skb);
2371 (u32) virt_to_bus(skb->data), 0, 0);
2372 2382
2373 } 2383 }
2374 else /* len > NS_SMBUFSIZE, the usual case */ 2384 else /* len > NS_SMBUFSIZE, the usual case */
2375 { 2385 {
2376 if (!atm_charge(vcc, skb->truesize)) 2386 if (!atm_charge(vcc, skb->truesize))
2377 { 2387 {
2378 push_rxbufs(card, BUF_LG, (u32) skb, 2388 push_rxbufs(card, skb);
2379 (u32) virt_to_bus(skb->data), 0, 0);
2380 atomic_inc(&vcc->stats->rx_drop); 2389 atomic_inc(&vcc->stats->rx_drop);
2381 } 2390 }
2382 else 2391 else
@@ -2389,13 +2398,12 @@ static void dequeue_rx(ns_dev *card, ns_rsqe *rsqe)
2389 memcpy(skb->data, sb->data, NS_SMBUFSIZE); 2398 memcpy(skb->data, sb->data, NS_SMBUFSIZE);
2390 skb_put(skb, len - NS_SMBUFSIZE); 2399 skb_put(skb, len - NS_SMBUFSIZE);
2391 ATM_SKB(skb)->vcc = vcc; 2400 ATM_SKB(skb)->vcc = vcc;
2392 do_gettimeofday(&skb->stamp); 2401 __net_timestamp(skb);
2393 vcc->push(vcc, skb); 2402 vcc->push(vcc, skb);
2394 atomic_inc(&vcc->stats->rx); 2403 atomic_inc(&vcc->stats->rx);
2395 } 2404 }
2396 2405
2397 push_rxbufs(card, BUF_SM, (u32) sb, (u32) virt_to_bus(sb->data), 2406 push_rxbufs(card, sb);
2398 0, 0);
2399 2407
2400 } 2408 }
2401 2409
@@ -2430,6 +2438,7 @@ static void dequeue_rx(ns_dev *card, ns_rsqe *rsqe)
2430 card->hbpool.count++; 2438 card->hbpool.count++;
2431 } 2439 }
2432 } 2440 }
2441 NS_SKB_CB(hb)->buf_type = BUF_NONE;
2433 } 2442 }
2434 else 2443 else
2435 if (--card->hbpool.count < card->hbnr.min) 2444 if (--card->hbpool.count < card->hbnr.min)
@@ -2437,6 +2446,7 @@ static void dequeue_rx(ns_dev *card, ns_rsqe *rsqe)
2437 struct sk_buff *new_hb; 2446 struct sk_buff *new_hb;
2438 if ((new_hb = dev_alloc_skb(NS_HBUFSIZE)) != NULL) 2447 if ((new_hb = dev_alloc_skb(NS_HBUFSIZE)) != NULL)
2439 { 2448 {
2449 NS_SKB_CB(new_hb)->buf_type = BUF_NONE;
2440 skb_queue_tail(&card->hbpool.queue, new_hb); 2450 skb_queue_tail(&card->hbpool.queue, new_hb);
2441 card->hbpool.count++; 2451 card->hbpool.count++;
2442 } 2452 }
@@ -2444,6 +2454,7 @@ static void dequeue_rx(ns_dev *card, ns_rsqe *rsqe)
2444 { 2454 {
2445 if ((new_hb = dev_alloc_skb(NS_HBUFSIZE)) != NULL) 2455 if ((new_hb = dev_alloc_skb(NS_HBUFSIZE)) != NULL)
2446 { 2456 {
2457 NS_SKB_CB(new_hb)->buf_type = BUF_NONE;
2447 skb_queue_tail(&card->hbpool.queue, new_hb); 2458 skb_queue_tail(&card->hbpool.queue, new_hb);
2448 card->hbpool.count++; 2459 card->hbpool.count++;
2449 } 2460 }
@@ -2473,8 +2484,7 @@ static void dequeue_rx(ns_dev *card, ns_rsqe *rsqe)
2473 remaining = len - iov->iov_len; 2484 remaining = len - iov->iov_len;
2474 iov++; 2485 iov++;
2475 /* Free the small buffer */ 2486 /* Free the small buffer */
2476 push_rxbufs(card, BUF_SM, (u32) sb, (u32) virt_to_bus(sb->data), 2487 push_rxbufs(card, sb);
2477 0, 0);
2478 2488
2479 /* Copy all large buffers to the huge buffer and free them */ 2489 /* Copy all large buffers to the huge buffer and free them */
2480 for (j = 1; j < NS_SKB(iovb)->iovcnt; j++) 2490 for (j = 1; j < NS_SKB(iovb)->iovcnt; j++)
@@ -2485,8 +2495,7 @@ static void dequeue_rx(ns_dev *card, ns_rsqe *rsqe)
2485 skb_put(hb, tocopy); 2495 skb_put(hb, tocopy);
2486 iov++; 2496 iov++;
2487 remaining -= tocopy; 2497 remaining -= tocopy;
2488 push_rxbufs(card, BUF_LG, (u32) lb, 2498 push_rxbufs(card, lb);
2489 (u32) virt_to_bus(lb->data), 0, 0);
2490 } 2499 }
2491#ifdef EXTRA_DEBUG 2500#ifdef EXTRA_DEBUG
2492 if (remaining != 0 || hb->len != len) 2501 if (remaining != 0 || hb->len != len)
@@ -2496,7 +2505,7 @@ static void dequeue_rx(ns_dev *card, ns_rsqe *rsqe)
2496#ifdef NS_USE_DESTRUCTORS 2505#ifdef NS_USE_DESTRUCTORS
2497 hb->destructor = ns_hb_destructor; 2506 hb->destructor = ns_hb_destructor;
2498#endif /* NS_USE_DESTRUCTORS */ 2507#endif /* NS_USE_DESTRUCTORS */
2499 do_gettimeofday(&hb->stamp); 2508 __net_timestamp(hb);
2500 vcc->push(vcc, hb); 2509 vcc->push(vcc, hb);
2501 atomic_inc(&vcc->stats->rx); 2510 atomic_inc(&vcc->stats->rx);
2502 } 2511 }
@@ -2527,9 +2536,10 @@ static void ns_sb_destructor(struct sk_buff *sb)
2527 sb = __dev_alloc_skb(NS_SMSKBSIZE, GFP_KERNEL); 2536 sb = __dev_alloc_skb(NS_SMSKBSIZE, GFP_KERNEL);
2528 if (sb == NULL) 2537 if (sb == NULL)
2529 break; 2538 break;
2539 NS_SKB_CB(sb)->buf_type = BUF_SM;
2530 skb_queue_tail(&card->sbpool.queue, sb); 2540 skb_queue_tail(&card->sbpool.queue, sb);
2531 skb_reserve(sb, NS_AAL0_HEADER); 2541 skb_reserve(sb, NS_AAL0_HEADER);
2532 push_rxbufs(card, BUF_SM, (u32) sb, (u32) virt_to_bus(sb->data), 0, 0); 2542 push_rxbufs(card, sb);
2533 } while (card->sbfqc < card->sbnr.min); 2543 } while (card->sbfqc < card->sbnr.min);
2534} 2544}
2535 2545
@@ -2550,9 +2560,10 @@ static void ns_lb_destructor(struct sk_buff *lb)
2550 lb = __dev_alloc_skb(NS_LGSKBSIZE, GFP_KERNEL); 2560 lb = __dev_alloc_skb(NS_LGSKBSIZE, GFP_KERNEL);
2551 if (lb == NULL) 2561 if (lb == NULL)
2552 break; 2562 break;
2563 NS_SKB_CB(lb)->buf_type = BUF_LG;
2553 skb_queue_tail(&card->lbpool.queue, lb); 2564 skb_queue_tail(&card->lbpool.queue, lb);
2554 skb_reserve(lb, NS_SMBUFSIZE); 2565 skb_reserve(lb, NS_SMBUFSIZE);
2555 push_rxbufs(card, BUF_LG, (u32) lb, (u32) virt_to_bus(lb->data), 0, 0); 2566 push_rxbufs(card, lb);
2556 } while (card->lbfqc < card->lbnr.min); 2567 } while (card->lbfqc < card->lbnr.min);
2557} 2568}
2558 2569
@@ -2569,6 +2580,7 @@ static void ns_hb_destructor(struct sk_buff *hb)
2569 hb = __dev_alloc_skb(NS_HBUFSIZE, GFP_KERNEL); 2580 hb = __dev_alloc_skb(NS_HBUFSIZE, GFP_KERNEL);
2570 if (hb == NULL) 2581 if (hb == NULL)
2571 break; 2582 break;
2583 NS_SKB_CB(hb)->buf_type = BUF_NONE;
2572 skb_queue_tail(&card->hbpool.queue, hb); 2584 skb_queue_tail(&card->hbpool.queue, hb);
2573 card->hbpool.count++; 2585 card->hbpool.count++;
2574 } 2586 }
@@ -2577,45 +2589,25 @@ static void ns_hb_destructor(struct sk_buff *hb)
2577#endif /* NS_USE_DESTRUCTORS */ 2589#endif /* NS_USE_DESTRUCTORS */
2578 2590
2579 2591
2580
2581static void recycle_rx_buf(ns_dev *card, struct sk_buff *skb) 2592static void recycle_rx_buf(ns_dev *card, struct sk_buff *skb)
2582{ 2593{
2583 if (skb->list == &card->sbpool.queue) 2594 struct ns_skb_cb *cb = NS_SKB_CB(skb);
2584 push_rxbufs(card, BUF_SM, (u32) skb, (u32) virt_to_bus(skb->data), 0, 0);
2585 else if (skb->list == &card->lbpool.queue)
2586 push_rxbufs(card, BUF_LG, (u32) skb, (u32) virt_to_bus(skb->data), 0, 0);
2587 else
2588 {
2589 printk("nicstar%d: What kind of rx buffer is this?\n", card->index);
2590 dev_kfree_skb_any(skb);
2591 }
2592}
2593 2595
2596 if (unlikely(cb->buf_type == BUF_NONE)) {
2597 printk("nicstar%d: What kind of rx buffer is this?\n", card->index);
2598 dev_kfree_skb_any(skb);
2599 } else
2600 push_rxbufs(card, skb);
2601}
2594 2602
2595 2603
2596static void recycle_iovec_rx_bufs(ns_dev *card, struct iovec *iov, int count) 2604static void recycle_iovec_rx_bufs(ns_dev *card, struct iovec *iov, int count)
2597{ 2605{
2598 struct sk_buff *skb; 2606 while (count-- > 0)
2599 2607 recycle_rx_buf(card, (struct sk_buff *) (iov++)->iov_base);
2600 for (; count > 0; count--)
2601 {
2602 skb = (struct sk_buff *) (iov++)->iov_base;
2603 if (skb->list == &card->sbpool.queue)
2604 push_rxbufs(card, BUF_SM, (u32) skb, (u32) virt_to_bus(skb->data),
2605 0, 0);
2606 else if (skb->list == &card->lbpool.queue)
2607 push_rxbufs(card, BUF_LG, (u32) skb, (u32) virt_to_bus(skb->data),
2608 0, 0);
2609 else
2610 {
2611 printk("nicstar%d: What kind of rx buffer is this?\n", card->index);
2612 dev_kfree_skb_any(skb);
2613 }
2614 }
2615} 2608}
2616 2609
2617 2610
2618
2619static void recycle_iov_buf(ns_dev *card, struct sk_buff *iovb) 2611static void recycle_iov_buf(ns_dev *card, struct sk_buff *iovb)
2620{ 2612{
2621 if (card->iovpool.count < card->iovnr.max) 2613 if (card->iovpool.count < card->iovnr.max)
@@ -2631,7 +2623,7 @@ static void recycle_iov_buf(ns_dev *card, struct sk_buff *iovb)
2631 2623
2632static void dequeue_sm_buf(ns_dev *card, struct sk_buff *sb) 2624static void dequeue_sm_buf(ns_dev *card, struct sk_buff *sb)
2633{ 2625{
2634 skb_unlink(sb); 2626 skb_unlink(sb, &card->sbpool.queue);
2635#ifdef NS_USE_DESTRUCTORS 2627#ifdef NS_USE_DESTRUCTORS
2636 if (card->sbfqc < card->sbnr.min) 2628 if (card->sbfqc < card->sbnr.min)
2637#else 2629#else
@@ -2640,10 +2632,10 @@ static void dequeue_sm_buf(ns_dev *card, struct sk_buff *sb)
2640 struct sk_buff *new_sb; 2632 struct sk_buff *new_sb;
2641 if ((new_sb = dev_alloc_skb(NS_SMSKBSIZE)) != NULL) 2633 if ((new_sb = dev_alloc_skb(NS_SMSKBSIZE)) != NULL)
2642 { 2634 {
2635 NS_SKB_CB(new_sb)->buf_type = BUF_SM;
2643 skb_queue_tail(&card->sbpool.queue, new_sb); 2636 skb_queue_tail(&card->sbpool.queue, new_sb);
2644 skb_reserve(new_sb, NS_AAL0_HEADER); 2637 skb_reserve(new_sb, NS_AAL0_HEADER);
2645 push_rxbufs(card, BUF_SM, (u32) new_sb, 2638 push_rxbufs(card, new_sb);
2646 (u32) virt_to_bus(new_sb->data), 0, 0);
2647 } 2639 }
2648 } 2640 }
2649 if (card->sbfqc < card->sbnr.init) 2641 if (card->sbfqc < card->sbnr.init)
@@ -2652,10 +2644,10 @@ static void dequeue_sm_buf(ns_dev *card, struct sk_buff *sb)
2652 struct sk_buff *new_sb; 2644 struct sk_buff *new_sb;
2653 if ((new_sb = dev_alloc_skb(NS_SMSKBSIZE)) != NULL) 2645 if ((new_sb = dev_alloc_skb(NS_SMSKBSIZE)) != NULL)
2654 { 2646 {
2647 NS_SKB_CB(new_sb)->buf_type = BUF_SM;
2655 skb_queue_tail(&card->sbpool.queue, new_sb); 2648 skb_queue_tail(&card->sbpool.queue, new_sb);
2656 skb_reserve(new_sb, NS_AAL0_HEADER); 2649 skb_reserve(new_sb, NS_AAL0_HEADER);
2657 push_rxbufs(card, BUF_SM, (u32) new_sb, 2650 push_rxbufs(card, new_sb);
2658 (u32) virt_to_bus(new_sb->data), 0, 0);
2659 } 2651 }
2660 } 2652 }
2661} 2653}
@@ -2664,7 +2656,7 @@ static void dequeue_sm_buf(ns_dev *card, struct sk_buff *sb)
2664 2656
2665static void dequeue_lg_buf(ns_dev *card, struct sk_buff *lb) 2657static void dequeue_lg_buf(ns_dev *card, struct sk_buff *lb)
2666{ 2658{
2667 skb_unlink(lb); 2659 skb_unlink(lb, &card->lbpool.queue);
2668#ifdef NS_USE_DESTRUCTORS 2660#ifdef NS_USE_DESTRUCTORS
2669 if (card->lbfqc < card->lbnr.min) 2661 if (card->lbfqc < card->lbnr.min)
2670#else 2662#else
@@ -2673,10 +2665,10 @@ static void dequeue_lg_buf(ns_dev *card, struct sk_buff *lb)
2673 struct sk_buff *new_lb; 2665 struct sk_buff *new_lb;
2674 if ((new_lb = dev_alloc_skb(NS_LGSKBSIZE)) != NULL) 2666 if ((new_lb = dev_alloc_skb(NS_LGSKBSIZE)) != NULL)
2675 { 2667 {
2668 NS_SKB_CB(new_lb)->buf_type = BUF_LG;
2676 skb_queue_tail(&card->lbpool.queue, new_lb); 2669 skb_queue_tail(&card->lbpool.queue, new_lb);
2677 skb_reserve(new_lb, NS_SMBUFSIZE); 2670 skb_reserve(new_lb, NS_SMBUFSIZE);
2678 push_rxbufs(card, BUF_LG, (u32) new_lb, 2671 push_rxbufs(card, new_lb);
2679 (u32) virt_to_bus(new_lb->data), 0, 0);
2680 } 2672 }
2681 } 2673 }
2682 if (card->lbfqc < card->lbnr.init) 2674 if (card->lbfqc < card->lbnr.init)
@@ -2685,10 +2677,10 @@ static void dequeue_lg_buf(ns_dev *card, struct sk_buff *lb)
2685 struct sk_buff *new_lb; 2677 struct sk_buff *new_lb;
2686 if ((new_lb = dev_alloc_skb(NS_LGSKBSIZE)) != NULL) 2678 if ((new_lb = dev_alloc_skb(NS_LGSKBSIZE)) != NULL)
2687 { 2679 {
2680 NS_SKB_CB(new_lb)->buf_type = BUF_LG;
2688 skb_queue_tail(&card->lbpool.queue, new_lb); 2681 skb_queue_tail(&card->lbpool.queue, new_lb);
2689 skb_reserve(new_lb, NS_SMBUFSIZE); 2682 skb_reserve(new_lb, NS_SMBUFSIZE);
2690 push_rxbufs(card, BUF_LG, (u32) new_lb, 2683 push_rxbufs(card, new_lb);
2691 (u32) virt_to_bus(new_lb->data), 0, 0);
2692 } 2684 }
2693 } 2685 }
2694} 2686}
@@ -2880,9 +2872,10 @@ static int ns_ioctl(struct atm_dev *dev, unsigned int cmd, void __user *arg)
2880 sb = __dev_alloc_skb(NS_SMSKBSIZE, GFP_KERNEL); 2872 sb = __dev_alloc_skb(NS_SMSKBSIZE, GFP_KERNEL);
2881 if (sb == NULL) 2873 if (sb == NULL)
2882 return -ENOMEM; 2874 return -ENOMEM;
2875 NS_SKB_CB(sb)->buf_type = BUF_SM;
2883 skb_queue_tail(&card->sbpool.queue, sb); 2876 skb_queue_tail(&card->sbpool.queue, sb);
2884 skb_reserve(sb, NS_AAL0_HEADER); 2877 skb_reserve(sb, NS_AAL0_HEADER);
2885 push_rxbufs(card, BUF_SM, (u32) sb, (u32) virt_to_bus(sb->data), 0, 0); 2878 push_rxbufs(card, sb);
2886 } 2879 }
2887 break; 2880 break;
2888 2881
@@ -2894,9 +2887,10 @@ static int ns_ioctl(struct atm_dev *dev, unsigned int cmd, void __user *arg)
2894 lb = __dev_alloc_skb(NS_LGSKBSIZE, GFP_KERNEL); 2887 lb = __dev_alloc_skb(NS_LGSKBSIZE, GFP_KERNEL);
2895 if (lb == NULL) 2888 if (lb == NULL)
2896 return -ENOMEM; 2889 return -ENOMEM;
2890 NS_SKB_CB(lb)->buf_type = BUF_LG;
2897 skb_queue_tail(&card->lbpool.queue, lb); 2891 skb_queue_tail(&card->lbpool.queue, lb);
2898 skb_reserve(lb, NS_SMBUFSIZE); 2892 skb_reserve(lb, NS_SMBUFSIZE);
2899 push_rxbufs(card, BUF_LG, (u32) lb, (u32) virt_to_bus(lb->data), 0, 0); 2893 push_rxbufs(card, lb);
2900 } 2894 }
2901 break; 2895 break;
2902 2896
@@ -2923,6 +2917,7 @@ static int ns_ioctl(struct atm_dev *dev, unsigned int cmd, void __user *arg)
2923 hb = __dev_alloc_skb(NS_HBUFSIZE, GFP_KERNEL); 2917 hb = __dev_alloc_skb(NS_HBUFSIZE, GFP_KERNEL);
2924 if (hb == NULL) 2918 if (hb == NULL)
2925 return -ENOMEM; 2919 return -ENOMEM;
2920 NS_SKB_CB(hb)->buf_type = BUF_NONE;
2926 ns_grab_int_lock(card, flags); 2921 ns_grab_int_lock(card, flags);
2927 skb_queue_tail(&card->hbpool.queue, hb); 2922 skb_queue_tail(&card->hbpool.queue, hb);
2928 card->hbpool.count++; 2923 card->hbpool.count++;
@@ -2953,6 +2948,7 @@ static int ns_ioctl(struct atm_dev *dev, unsigned int cmd, void __user *arg)
2953 iovb = alloc_skb(NS_IOVBUFSIZE, GFP_KERNEL); 2948 iovb = alloc_skb(NS_IOVBUFSIZE, GFP_KERNEL);
2954 if (iovb == NULL) 2949 if (iovb == NULL)
2955 return -ENOMEM; 2950 return -ENOMEM;
2951 NS_SKB_CB(iovb)->buf_type = BUF_NONE;
2956 ns_grab_int_lock(card, flags); 2952 ns_grab_int_lock(card, flags);
2957 skb_queue_tail(&card->iovpool.queue, iovb); 2953 skb_queue_tail(&card->iovpool.queue, iovb);
2958 card->iovpool.count++; 2954 card->iovpool.count++;
@@ -2979,17 +2975,12 @@ static int ns_ioctl(struct atm_dev *dev, unsigned int cmd, void __user *arg)
2979} 2975}
2980 2976
2981 2977
2982
2983static void which_list(ns_dev *card, struct sk_buff *skb) 2978static void which_list(ns_dev *card, struct sk_buff *skb)
2984{ 2979{
2985 printk("It's a %s buffer.\n", skb->list == &card->sbpool.queue ? 2980 printk("skb buf_type: 0x%08x\n", NS_SKB_CB(skb)->buf_type);
2986 "small" : skb->list == &card->lbpool.queue ? "large" :
2987 skb->list == &card->hbpool.queue ? "huge" :
2988 skb->list == &card->iovpool.queue ? "iovec" : "unknown");
2989} 2981}
2990 2982
2991 2983
2992
2993static void ns_poll(unsigned long arg) 2984static void ns_poll(unsigned long arg)
2994{ 2985{
2995 int i; 2986 int i;
diff --git a/drivers/atm/nicstar.h b/drivers/atm/nicstar.h
index ea83c46c8ba5..5997bcb45b59 100644
--- a/drivers/atm/nicstar.h
+++ b/drivers/atm/nicstar.h
@@ -103,8 +103,14 @@
103 103
104#define NS_IOREMAP_SIZE 4096 104#define NS_IOREMAP_SIZE 4096
105 105
106#define BUF_SM 0x00000000 /* These two are used for push_rxbufs() */ 106/*
107#define BUF_LG 0x00000001 /* CMD, Write_FreeBufQ, LBUF bit */ 107 * BUF_XX distinguish the Rx buffers depending on their (small/large) size.
108 * BUG_SM and BUG_LG are both used by the driver and the device.
109 * BUF_NONE is only used by the driver.
110 */
111#define BUF_SM 0x00000000 /* These two are used for push_rxbufs() */
112#define BUF_LG 0x00000001 /* CMD, Write_FreeBufQ, LBUF bit */
113#define BUF_NONE 0xffffffff /* Software only: */
108 114
109#define NS_HBUFSIZE 65568 /* Size of max. AAL5 PDU */ 115#define NS_HBUFSIZE 65568 /* Size of max. AAL5 PDU */
110#define NS_MAX_IOVECS (2 + (65568 - NS_SMBUFSIZE) / \ 116#define NS_MAX_IOVECS (2 + (65568 - NS_SMBUFSIZE) / \
@@ -684,6 +690,12 @@ enum ns_regs
684/* Device driver structures ***************************************************/ 690/* Device driver structures ***************************************************/
685 691
686 692
693struct ns_skb_cb {
694 u32 buf_type; /* BUF_SM/BUF_LG/BUF_NONE */
695};
696
697#define NS_SKB_CB(skb) ((struct ns_skb_cb *)((skb)->cb))
698
687typedef struct tsq_info 699typedef struct tsq_info
688{ 700{
689 void *org; 701 void *org;
diff --git a/drivers/atm/zatm.c b/drivers/atm/zatm.c
index a2b236a966e0..c4b75ecf9460 100644
--- a/drivers/atm/zatm.c
+++ b/drivers/atm/zatm.c
@@ -400,7 +400,7 @@ unsigned long *x;
400EVENT("error code 0x%x/0x%x\n",(here[3] & uPD98401_AAL5_ES) >> 400EVENT("error code 0x%x/0x%x\n",(here[3] & uPD98401_AAL5_ES) >>
401 uPD98401_AAL5_ES_SHIFT,error); 401 uPD98401_AAL5_ES_SHIFT,error);
402 skb = ((struct rx_buffer_head *) bus_to_virt(here[2]))->skb; 402 skb = ((struct rx_buffer_head *) bus_to_virt(here[2]))->skb;
403 do_gettimeofday(&skb->stamp); 403 __net_timestamp(skb);
404#if 0 404#if 0
405printk("[-3..0] 0x%08lx 0x%08lx 0x%08lx 0x%08lx\n",((unsigned *) skb->data)[-3], 405printk("[-3..0] 0x%08lx 0x%08lx 0x%08lx 0x%08lx\n",((unsigned *) skb->data)[-3],
406 ((unsigned *) skb->data)[-2],((unsigned *) skb->data)[-1], 406 ((unsigned *) skb->data)[-2],((unsigned *) skb->data)[-1],
@@ -417,10 +417,12 @@ printk("dummy: 0x%08lx, 0x%08lx\n",dummy[0],dummy[1]);
417 chan = (here[3] & uPD98401_AAL5_CHAN) >> 417 chan = (here[3] & uPD98401_AAL5_CHAN) >>
418 uPD98401_AAL5_CHAN_SHIFT; 418 uPD98401_AAL5_CHAN_SHIFT;
419 if (chan < zatm_dev->chans && zatm_dev->rx_map[chan]) { 419 if (chan < zatm_dev->chans && zatm_dev->rx_map[chan]) {
420 int pos = ZATM_VCC(vcc)->pool;
421
420 vcc = zatm_dev->rx_map[chan]; 422 vcc = zatm_dev->rx_map[chan];
421 if (skb == zatm_dev->last_free[ZATM_VCC(vcc)->pool]) 423 if (skb == zatm_dev->last_free[pos])
422 zatm_dev->last_free[ZATM_VCC(vcc)->pool] = NULL; 424 zatm_dev->last_free[pos] = NULL;
423 skb_unlink(skb); 425 skb_unlink(skb, zatm_dev->pool + pos);
424 } 426 }
425 else { 427 else {
426 printk(KERN_ERR DEV_LABEL "(itf %d): RX indication " 428 printk(KERN_ERR DEV_LABEL "(itf %d): RX indication "
diff --git a/drivers/block/aoe/aoenet.c b/drivers/block/aoe/aoenet.c
index 9e6f51c528b0..4be976940f69 100644
--- a/drivers/block/aoe/aoenet.c
+++ b/drivers/block/aoe/aoenet.c
@@ -120,7 +120,7 @@ aoenet_xmit(struct sk_buff *sl)
120 * (1) len doesn't include the header by default. I want this. 120 * (1) len doesn't include the header by default. I want this.
121 */ 121 */
122static int 122static int
123aoenet_rcv(struct sk_buff *skb, struct net_device *ifp, struct packet_type *pt) 123aoenet_rcv(struct sk_buff *skb, struct net_device *ifp, struct packet_type *pt, struct net_device *orig_dev)
124{ 124{
125 struct aoe_hdr *h; 125 struct aoe_hdr *h;
126 u32 n; 126 u32 n;
diff --git a/drivers/block/viodasd.c b/drivers/block/viodasd.c
index 46e56a25d2c8..e46ecd23b3ac 100644
--- a/drivers/block/viodasd.c
+++ b/drivers/block/viodasd.c
@@ -776,7 +776,7 @@ static int viodasd_remove(struct vio_dev *vdev)
776 */ 776 */
777static struct vio_device_id viodasd_device_table[] __devinitdata = { 777static struct vio_device_id viodasd_device_table[] __devinitdata = {
778 { "viodasd", "" }, 778 { "viodasd", "" },
779 { 0, } 779 { "", "" }
780}; 780};
781 781
782MODULE_DEVICE_TABLE(vio, viodasd_device_table); 782MODULE_DEVICE_TABLE(vio, viodasd_device_table);
diff --git a/drivers/bluetooth/bfusb.c b/drivers/bluetooth/bfusb.c
index c42d7e6ac1c5..1e9db0156ea7 100644
--- a/drivers/bluetooth/bfusb.c
+++ b/drivers/bluetooth/bfusb.c
@@ -158,7 +158,7 @@ static int bfusb_send_bulk(struct bfusb *bfusb, struct sk_buff *skb)
158 if (err) { 158 if (err) {
159 BT_ERR("%s bulk tx submit failed urb %p err %d", 159 BT_ERR("%s bulk tx submit failed urb %p err %d",
160 bfusb->hdev->name, urb, err); 160 bfusb->hdev->name, urb, err);
161 skb_unlink(skb); 161 skb_unlink(skb, &bfusb->pending_q);
162 usb_free_urb(urb); 162 usb_free_urb(urb);
163 } else 163 } else
164 atomic_inc(&bfusb->pending_tx); 164 atomic_inc(&bfusb->pending_tx);
@@ -212,7 +212,7 @@ static void bfusb_tx_complete(struct urb *urb, struct pt_regs *regs)
212 212
213 read_lock(&bfusb->lock); 213 read_lock(&bfusb->lock);
214 214
215 skb_unlink(skb); 215 skb_unlink(skb, &bfusb->pending_q);
216 skb_queue_tail(&bfusb->completed_q, skb); 216 skb_queue_tail(&bfusb->completed_q, skb);
217 217
218 bfusb_tx_wakeup(bfusb); 218 bfusb_tx_wakeup(bfusb);
@@ -253,7 +253,7 @@ static int bfusb_rx_submit(struct bfusb *bfusb, struct urb *urb)
253 if (err) { 253 if (err) {
254 BT_ERR("%s bulk rx submit failed urb %p err %d", 254 BT_ERR("%s bulk rx submit failed urb %p err %d",
255 bfusb->hdev->name, urb, err); 255 bfusb->hdev->name, urb, err);
256 skb_unlink(skb); 256 skb_unlink(skb, &bfusb->pending_q);
257 kfree_skb(skb); 257 kfree_skb(skb);
258 usb_free_urb(urb); 258 usb_free_urb(urb);
259 } 259 }
@@ -330,7 +330,7 @@ static inline int bfusb_recv_block(struct bfusb *bfusb, int hdr, unsigned char *
330 } 330 }
331 331
332 skb->dev = (void *) bfusb->hdev; 332 skb->dev = (void *) bfusb->hdev;
333 skb->pkt_type = pkt_type; 333 bt_cb(skb)->pkt_type = pkt_type;
334 334
335 bfusb->reassembly = skb; 335 bfusb->reassembly = skb;
336 } else { 336 } else {
@@ -398,7 +398,7 @@ static void bfusb_rx_complete(struct urb *urb, struct pt_regs *regs)
398 buf += len; 398 buf += len;
399 } 399 }
400 400
401 skb_unlink(skb); 401 skb_unlink(skb, &bfusb->pending_q);
402 kfree_skb(skb); 402 kfree_skb(skb);
403 403
404 bfusb_rx_submit(bfusb, urb); 404 bfusb_rx_submit(bfusb, urb);
@@ -485,7 +485,7 @@ static int bfusb_send_frame(struct sk_buff *skb)
485 unsigned char buf[3]; 485 unsigned char buf[3];
486 int sent = 0, size, count; 486 int sent = 0, size, count;
487 487
488 BT_DBG("hdev %p skb %p type %d len %d", hdev, skb, skb->pkt_type, skb->len); 488 BT_DBG("hdev %p skb %p type %d len %d", hdev, skb, bt_cb(skb)->pkt_type, skb->len);
489 489
490 if (!hdev) { 490 if (!hdev) {
491 BT_ERR("Frame for unknown HCI device (hdev=NULL)"); 491 BT_ERR("Frame for unknown HCI device (hdev=NULL)");
@@ -497,7 +497,7 @@ static int bfusb_send_frame(struct sk_buff *skb)
497 497
498 bfusb = (struct bfusb *) hdev->driver_data; 498 bfusb = (struct bfusb *) hdev->driver_data;
499 499
500 switch (skb->pkt_type) { 500 switch (bt_cb(skb)->pkt_type) {
501 case HCI_COMMAND_PKT: 501 case HCI_COMMAND_PKT:
502 hdev->stat.cmd_tx++; 502 hdev->stat.cmd_tx++;
503 break; 503 break;
@@ -510,7 +510,7 @@ static int bfusb_send_frame(struct sk_buff *skb)
510 }; 510 };
511 511
512 /* Prepend skb with frame type */ 512 /* Prepend skb with frame type */
513 memcpy(skb_push(skb, 1), &(skb->pkt_type), 1); 513 memcpy(skb_push(skb, 1), &bt_cb(skb)->pkt_type, 1);
514 514
515 count = skb->len; 515 count = skb->len;
516 516
diff --git a/drivers/bluetooth/bluecard_cs.c b/drivers/bluetooth/bluecard_cs.c
index bd2ec7e284cc..26fe9c0e1d20 100644
--- a/drivers/bluetooth/bluecard_cs.c
+++ b/drivers/bluetooth/bluecard_cs.c
@@ -270,7 +270,7 @@ static void bluecard_write_wakeup(bluecard_info_t *info)
270 if (!(skb = skb_dequeue(&(info->txq)))) 270 if (!(skb = skb_dequeue(&(info->txq))))
271 break; 271 break;
272 272
273 if (skb->pkt_type & 0x80) { 273 if (bt_cb(skb)->pkt_type & 0x80) {
274 /* Disable RTS */ 274 /* Disable RTS */
275 info->ctrl_reg |= REG_CONTROL_RTS; 275 info->ctrl_reg |= REG_CONTROL_RTS;
276 outb(info->ctrl_reg, iobase + REG_CONTROL); 276 outb(info->ctrl_reg, iobase + REG_CONTROL);
@@ -288,13 +288,13 @@ static void bluecard_write_wakeup(bluecard_info_t *info)
288 /* Mark the buffer as dirty */ 288 /* Mark the buffer as dirty */
289 clear_bit(ready_bit, &(info->tx_state)); 289 clear_bit(ready_bit, &(info->tx_state));
290 290
291 if (skb->pkt_type & 0x80) { 291 if (bt_cb(skb)->pkt_type & 0x80) {
292 DECLARE_WAIT_QUEUE_HEAD(wq); 292 DECLARE_WAIT_QUEUE_HEAD(wq);
293 DEFINE_WAIT(wait); 293 DEFINE_WAIT(wait);
294 294
295 unsigned char baud_reg; 295 unsigned char baud_reg;
296 296
297 switch (skb->pkt_type) { 297 switch (bt_cb(skb)->pkt_type) {
298 case PKT_BAUD_RATE_460800: 298 case PKT_BAUD_RATE_460800:
299 baud_reg = REG_CONTROL_BAUD_RATE_460800; 299 baud_reg = REG_CONTROL_BAUD_RATE_460800;
300 break; 300 break;
@@ -410,9 +410,9 @@ static void bluecard_receive(bluecard_info_t *info, unsigned int offset)
410 if (info->rx_state == RECV_WAIT_PACKET_TYPE) { 410 if (info->rx_state == RECV_WAIT_PACKET_TYPE) {
411 411
412 info->rx_skb->dev = (void *) info->hdev; 412 info->rx_skb->dev = (void *) info->hdev;
413 info->rx_skb->pkt_type = buf[i]; 413 bt_cb(info->rx_skb)->pkt_type = buf[i];
414 414
415 switch (info->rx_skb->pkt_type) { 415 switch (bt_cb(info->rx_skb)->pkt_type) {
416 416
417 case 0x00: 417 case 0x00:
418 /* init packet */ 418 /* init packet */
@@ -444,7 +444,7 @@ static void bluecard_receive(bluecard_info_t *info, unsigned int offset)
444 444
445 default: 445 default:
446 /* unknown packet */ 446 /* unknown packet */
447 BT_ERR("Unknown HCI packet with type 0x%02x received", info->rx_skb->pkt_type); 447 BT_ERR("Unknown HCI packet with type 0x%02x received", bt_cb(info->rx_skb)->pkt_type);
448 info->hdev->stat.err_rx++; 448 info->hdev->stat.err_rx++;
449 449
450 kfree_skb(info->rx_skb); 450 kfree_skb(info->rx_skb);
@@ -586,21 +586,21 @@ static int bluecard_hci_set_baud_rate(struct hci_dev *hdev, int baud)
586 switch (baud) { 586 switch (baud) {
587 case 460800: 587 case 460800:
588 cmd[4] = 0x00; 588 cmd[4] = 0x00;
589 skb->pkt_type = PKT_BAUD_RATE_460800; 589 bt_cb(skb)->pkt_type = PKT_BAUD_RATE_460800;
590 break; 590 break;
591 case 230400: 591 case 230400:
592 cmd[4] = 0x01; 592 cmd[4] = 0x01;
593 skb->pkt_type = PKT_BAUD_RATE_230400; 593 bt_cb(skb)->pkt_type = PKT_BAUD_RATE_230400;
594 break; 594 break;
595 case 115200: 595 case 115200:
596 cmd[4] = 0x02; 596 cmd[4] = 0x02;
597 skb->pkt_type = PKT_BAUD_RATE_115200; 597 bt_cb(skb)->pkt_type = PKT_BAUD_RATE_115200;
598 break; 598 break;
599 case 57600: 599 case 57600:
600 /* Fall through... */ 600 /* Fall through... */
601 default: 601 default:
602 cmd[4] = 0x03; 602 cmd[4] = 0x03;
603 skb->pkt_type = PKT_BAUD_RATE_57600; 603 bt_cb(skb)->pkt_type = PKT_BAUD_RATE_57600;
604 break; 604 break;
605 } 605 }
606 606
@@ -680,7 +680,7 @@ static int bluecard_hci_send_frame(struct sk_buff *skb)
680 680
681 info = (bluecard_info_t *)(hdev->driver_data); 681 info = (bluecard_info_t *)(hdev->driver_data);
682 682
683 switch (skb->pkt_type) { 683 switch (bt_cb(skb)->pkt_type) {
684 case HCI_COMMAND_PKT: 684 case HCI_COMMAND_PKT:
685 hdev->stat.cmd_tx++; 685 hdev->stat.cmd_tx++;
686 break; 686 break;
@@ -693,7 +693,7 @@ static int bluecard_hci_send_frame(struct sk_buff *skb)
693 }; 693 };
694 694
695 /* Prepend skb with frame type */ 695 /* Prepend skb with frame type */
696 memcpy(skb_push(skb, 1), &(skb->pkt_type), 1); 696 memcpy(skb_push(skb, 1), &bt_cb(skb)->pkt_type, 1);
697 skb_queue_tail(&(info->txq), skb); 697 skb_queue_tail(&(info->txq), skb);
698 698
699 bluecard_write_wakeup(info); 699 bluecard_write_wakeup(info);
diff --git a/drivers/bluetooth/bpa10x.c b/drivers/bluetooth/bpa10x.c
index f696da6f417b..a1bf8f066c88 100644
--- a/drivers/bluetooth/bpa10x.c
+++ b/drivers/bluetooth/bpa10x.c
@@ -105,7 +105,7 @@ static void bpa10x_recv_bulk(struct bpa10x_data *data, unsigned char *buf, int c
105 if (skb) { 105 if (skb) {
106 memcpy(skb_put(skb, len), buf, len); 106 memcpy(skb_put(skb, len), buf, len);
107 skb->dev = (void *) data->hdev; 107 skb->dev = (void *) data->hdev;
108 skb->pkt_type = HCI_ACLDATA_PKT; 108 bt_cb(skb)->pkt_type = HCI_ACLDATA_PKT;
109 hci_recv_frame(skb); 109 hci_recv_frame(skb);
110 } 110 }
111 break; 111 break;
@@ -117,7 +117,7 @@ static void bpa10x_recv_bulk(struct bpa10x_data *data, unsigned char *buf, int c
117 if (skb) { 117 if (skb) {
118 memcpy(skb_put(skb, len), buf, len); 118 memcpy(skb_put(skb, len), buf, len);
119 skb->dev = (void *) data->hdev; 119 skb->dev = (void *) data->hdev;
120 skb->pkt_type = HCI_SCODATA_PKT; 120 bt_cb(skb)->pkt_type = HCI_SCODATA_PKT;
121 hci_recv_frame(skb); 121 hci_recv_frame(skb);
122 } 122 }
123 break; 123 break;
@@ -129,7 +129,7 @@ static void bpa10x_recv_bulk(struct bpa10x_data *data, unsigned char *buf, int c
129 if (skb) { 129 if (skb) {
130 memcpy(skb_put(skb, len), buf, len); 130 memcpy(skb_put(skb, len), buf, len);
131 skb->dev = (void *) data->hdev; 131 skb->dev = (void *) data->hdev;
132 skb->pkt_type = HCI_VENDOR_PKT; 132 bt_cb(skb)->pkt_type = HCI_VENDOR_PKT;
133 hci_recv_frame(skb); 133 hci_recv_frame(skb);
134 } 134 }
135 break; 135 break;
@@ -190,7 +190,7 @@ static int bpa10x_recv_event(struct bpa10x_data *data, unsigned char *buf, int s
190 } 190 }
191 191
192 skb->dev = (void *) data->hdev; 192 skb->dev = (void *) data->hdev;
193 skb->pkt_type = pkt_type; 193 bt_cb(skb)->pkt_type = pkt_type;
194 194
195 memcpy(skb_put(skb, size), buf, size); 195 memcpy(skb_put(skb, size), buf, size);
196 196
@@ -307,7 +307,8 @@ unlock:
307 read_unlock(&data->lock); 307 read_unlock(&data->lock);
308} 308}
309 309
310static inline struct urb *bpa10x_alloc_urb(struct usb_device *udev, unsigned int pipe, size_t size, int flags, void *data) 310static inline struct urb *bpa10x_alloc_urb(struct usb_device *udev, unsigned int pipe,
311 size_t size, unsigned int __nocast flags, void *data)
311{ 312{
312 struct urb *urb; 313 struct urb *urb;
313 struct usb_ctrlrequest *cr; 314 struct usb_ctrlrequest *cr;
@@ -487,7 +488,7 @@ static int bpa10x_send_frame(struct sk_buff *skb)
487 struct hci_dev *hdev = (struct hci_dev *) skb->dev; 488 struct hci_dev *hdev = (struct hci_dev *) skb->dev;
488 struct bpa10x_data *data; 489 struct bpa10x_data *data;
489 490
490 BT_DBG("hdev %p skb %p type %d len %d", hdev, skb, skb->pkt_type, skb->len); 491 BT_DBG("hdev %p skb %p type %d len %d", hdev, skb, bt_cb(skb)->pkt_type, skb->len);
491 492
492 if (!hdev) { 493 if (!hdev) {
493 BT_ERR("Frame for unknown HCI device"); 494 BT_ERR("Frame for unknown HCI device");
@@ -500,9 +501,9 @@ static int bpa10x_send_frame(struct sk_buff *skb)
500 data = hdev->driver_data; 501 data = hdev->driver_data;
501 502
502 /* Prepend skb with frame type */ 503 /* Prepend skb with frame type */
503 memcpy(skb_push(skb, 1), &(skb->pkt_type), 1); 504 memcpy(skb_push(skb, 1), &bt_cb(skb)->pkt_type, 1);
504 505
505 switch (skb->pkt_type) { 506 switch (bt_cb(skb)->pkt_type) {
506 case HCI_COMMAND_PKT: 507 case HCI_COMMAND_PKT:
507 hdev->stat.cmd_tx++; 508 hdev->stat.cmd_tx++;
508 skb_queue_tail(&data->cmd_queue, skb); 509 skb_queue_tail(&data->cmd_queue, skb);
diff --git a/drivers/bluetooth/bt3c_cs.c b/drivers/bluetooth/bt3c_cs.c
index adf1750ea58d..2e0338d80f32 100644
--- a/drivers/bluetooth/bt3c_cs.c
+++ b/drivers/bluetooth/bt3c_cs.c
@@ -259,11 +259,11 @@ static void bt3c_receive(bt3c_info_t *info)
259 if (info->rx_state == RECV_WAIT_PACKET_TYPE) { 259 if (info->rx_state == RECV_WAIT_PACKET_TYPE) {
260 260
261 info->rx_skb->dev = (void *) info->hdev; 261 info->rx_skb->dev = (void *) info->hdev;
262 info->rx_skb->pkt_type = inb(iobase + DATA_L); 262 bt_cb(info->rx_skb)->pkt_type = inb(iobase + DATA_L);
263 inb(iobase + DATA_H); 263 inb(iobase + DATA_H);
264 //printk("bt3c: PACKET_TYPE=%02x\n", info->rx_skb->pkt_type); 264 //printk("bt3c: PACKET_TYPE=%02x\n", bt_cb(info->rx_skb)->pkt_type);
265 265
266 switch (info->rx_skb->pkt_type) { 266 switch (bt_cb(info->rx_skb)->pkt_type) {
267 267
268 case HCI_EVENT_PKT: 268 case HCI_EVENT_PKT:
269 info->rx_state = RECV_WAIT_EVENT_HEADER; 269 info->rx_state = RECV_WAIT_EVENT_HEADER;
@@ -282,7 +282,7 @@ static void bt3c_receive(bt3c_info_t *info)
282 282
283 default: 283 default:
284 /* Unknown packet */ 284 /* Unknown packet */
285 BT_ERR("Unknown HCI packet with type 0x%02x received", info->rx_skb->pkt_type); 285 BT_ERR("Unknown HCI packet with type 0x%02x received", bt_cb(info->rx_skb)->pkt_type);
286 info->hdev->stat.err_rx++; 286 info->hdev->stat.err_rx++;
287 clear_bit(HCI_RUNNING, &(info->hdev->flags)); 287 clear_bit(HCI_RUNNING, &(info->hdev->flags));
288 288
@@ -439,7 +439,7 @@ static int bt3c_hci_send_frame(struct sk_buff *skb)
439 439
440 info = (bt3c_info_t *) (hdev->driver_data); 440 info = (bt3c_info_t *) (hdev->driver_data);
441 441
442 switch (skb->pkt_type) { 442 switch (bt_cb(skb)->pkt_type) {
443 case HCI_COMMAND_PKT: 443 case HCI_COMMAND_PKT:
444 hdev->stat.cmd_tx++; 444 hdev->stat.cmd_tx++;
445 break; 445 break;
@@ -452,7 +452,7 @@ static int bt3c_hci_send_frame(struct sk_buff *skb)
452 }; 452 };
453 453
454 /* Prepend skb with frame type */ 454 /* Prepend skb with frame type */
455 memcpy(skb_push(skb, 1), &(skb->pkt_type), 1); 455 memcpy(skb_push(skb, 1), &bt_cb(skb)->pkt_type, 1);
456 skb_queue_tail(&(info->txq), skb); 456 skb_queue_tail(&(info->txq), skb);
457 457
458 spin_lock_irqsave(&(info->lock), flags); 458 spin_lock_irqsave(&(info->lock), flags);
diff --git a/drivers/bluetooth/btuart_cs.c b/drivers/bluetooth/btuart_cs.c
index e4c59fdc0e12..89486ea7a021 100644
--- a/drivers/bluetooth/btuart_cs.c
+++ b/drivers/bluetooth/btuart_cs.c
@@ -211,9 +211,9 @@ static void btuart_receive(btuart_info_t *info)
211 if (info->rx_state == RECV_WAIT_PACKET_TYPE) { 211 if (info->rx_state == RECV_WAIT_PACKET_TYPE) {
212 212
213 info->rx_skb->dev = (void *) info->hdev; 213 info->rx_skb->dev = (void *) info->hdev;
214 info->rx_skb->pkt_type = inb(iobase + UART_RX); 214 bt_cb(info->rx_skb)->pkt_type = inb(iobase + UART_RX);
215 215
216 switch (info->rx_skb->pkt_type) { 216 switch (bt_cb(info->rx_skb)->pkt_type) {
217 217
218 case HCI_EVENT_PKT: 218 case HCI_EVENT_PKT:
219 info->rx_state = RECV_WAIT_EVENT_HEADER; 219 info->rx_state = RECV_WAIT_EVENT_HEADER;
@@ -232,7 +232,7 @@ static void btuart_receive(btuart_info_t *info)
232 232
233 default: 233 default:
234 /* Unknown packet */ 234 /* Unknown packet */
235 BT_ERR("Unknown HCI packet with type 0x%02x received", info->rx_skb->pkt_type); 235 BT_ERR("Unknown HCI packet with type 0x%02x received", bt_cb(info->rx_skb)->pkt_type);
236 info->hdev->stat.err_rx++; 236 info->hdev->stat.err_rx++;
237 clear_bit(HCI_RUNNING, &(info->hdev->flags)); 237 clear_bit(HCI_RUNNING, &(info->hdev->flags));
238 238
@@ -447,7 +447,7 @@ static int btuart_hci_send_frame(struct sk_buff *skb)
447 447
448 info = (btuart_info_t *)(hdev->driver_data); 448 info = (btuart_info_t *)(hdev->driver_data);
449 449
450 switch (skb->pkt_type) { 450 switch (bt_cb(skb)->pkt_type) {
451 case HCI_COMMAND_PKT: 451 case HCI_COMMAND_PKT:
452 hdev->stat.cmd_tx++; 452 hdev->stat.cmd_tx++;
453 break; 453 break;
@@ -460,7 +460,7 @@ static int btuart_hci_send_frame(struct sk_buff *skb)
460 }; 460 };
461 461
462 /* Prepend skb with frame type */ 462 /* Prepend skb with frame type */
463 memcpy(skb_push(skb, 1), &(skb->pkt_type), 1); 463 memcpy(skb_push(skb, 1), &bt_cb(skb)->pkt_type, 1);
464 skb_queue_tail(&(info->txq), skb); 464 skb_queue_tail(&(info->txq), skb);
465 465
466 btuart_write_wakeup(info); 466 btuart_write_wakeup(info);
diff --git a/drivers/bluetooth/dtl1_cs.c b/drivers/bluetooth/dtl1_cs.c
index e39868c3da48..84c1f8839422 100644
--- a/drivers/bluetooth/dtl1_cs.c
+++ b/drivers/bluetooth/dtl1_cs.c
@@ -251,7 +251,7 @@ static void dtl1_receive(dtl1_info_t *info)
251 info->rx_count = nsh->len + (nsh->len & 0x0001); 251 info->rx_count = nsh->len + (nsh->len & 0x0001);
252 break; 252 break;
253 case RECV_WAIT_DATA: 253 case RECV_WAIT_DATA:
254 info->rx_skb->pkt_type = nsh->type; 254 bt_cb(info->rx_skb)->pkt_type = nsh->type;
255 255
256 /* remove PAD byte if it exists */ 256 /* remove PAD byte if it exists */
257 if (nsh->len & 0x0001) { 257 if (nsh->len & 0x0001) {
@@ -262,7 +262,7 @@ static void dtl1_receive(dtl1_info_t *info)
262 /* remove NSH */ 262 /* remove NSH */
263 skb_pull(info->rx_skb, NSHL); 263 skb_pull(info->rx_skb, NSHL);
264 264
265 switch (info->rx_skb->pkt_type) { 265 switch (bt_cb(info->rx_skb)->pkt_type) {
266 case 0x80: 266 case 0x80:
267 /* control data for the Nokia Card */ 267 /* control data for the Nokia Card */
268 dtl1_control(info, info->rx_skb); 268 dtl1_control(info, info->rx_skb);
@@ -272,12 +272,12 @@ static void dtl1_receive(dtl1_info_t *info)
272 case 0x84: 272 case 0x84:
273 /* send frame to the HCI layer */ 273 /* send frame to the HCI layer */
274 info->rx_skb->dev = (void *) info->hdev; 274 info->rx_skb->dev = (void *) info->hdev;
275 info->rx_skb->pkt_type &= 0x0f; 275 bt_cb(info->rx_skb)->pkt_type &= 0x0f;
276 hci_recv_frame(info->rx_skb); 276 hci_recv_frame(info->rx_skb);
277 break; 277 break;
278 default: 278 default:
279 /* unknown packet */ 279 /* unknown packet */
280 BT_ERR("Unknown HCI packet with type 0x%02x received", info->rx_skb->pkt_type); 280 BT_ERR("Unknown HCI packet with type 0x%02x received", bt_cb(info->rx_skb)->pkt_type);
281 kfree_skb(info->rx_skb); 281 kfree_skb(info->rx_skb);
282 break; 282 break;
283 } 283 }
@@ -410,7 +410,7 @@ static int dtl1_hci_send_frame(struct sk_buff *skb)
410 410
411 info = (dtl1_info_t *)(hdev->driver_data); 411 info = (dtl1_info_t *)(hdev->driver_data);
412 412
413 switch (skb->pkt_type) { 413 switch (bt_cb(skb)->pkt_type) {
414 case HCI_COMMAND_PKT: 414 case HCI_COMMAND_PKT:
415 hdev->stat.cmd_tx++; 415 hdev->stat.cmd_tx++;
416 nsh.type = 0x81; 416 nsh.type = 0x81;
diff --git a/drivers/bluetooth/hci_bcsp.c b/drivers/bluetooth/hci_bcsp.c
index 858fddb046de..0ee324e1265d 100644
--- a/drivers/bluetooth/hci_bcsp.c
+++ b/drivers/bluetooth/hci_bcsp.c
@@ -149,7 +149,7 @@ static int bcsp_enqueue(struct hci_uart *hu, struct sk_buff *skb)
149 return 0; 149 return 0;
150 } 150 }
151 151
152 switch (skb->pkt_type) { 152 switch (bt_cb(skb)->pkt_type) {
153 case HCI_ACLDATA_PKT: 153 case HCI_ACLDATA_PKT:
154 case HCI_COMMAND_PKT: 154 case HCI_COMMAND_PKT:
155 skb_queue_tail(&bcsp->rel, skb); 155 skb_queue_tail(&bcsp->rel, skb);
@@ -227,7 +227,7 @@ static struct sk_buff *bcsp_prepare_pkt(struct bcsp_struct *bcsp, u8 *data,
227 if (!nskb) 227 if (!nskb)
228 return NULL; 228 return NULL;
229 229
230 nskb->pkt_type = pkt_type; 230 bt_cb(nskb)->pkt_type = pkt_type;
231 231
232 bcsp_slip_msgdelim(nskb); 232 bcsp_slip_msgdelim(nskb);
233 233
@@ -286,7 +286,7 @@ static struct sk_buff *bcsp_dequeue(struct hci_uart *hu)
286 since they have priority */ 286 since they have priority */
287 287
288 if ((skb = skb_dequeue(&bcsp->unrel)) != NULL) { 288 if ((skb = skb_dequeue(&bcsp->unrel)) != NULL) {
289 struct sk_buff *nskb = bcsp_prepare_pkt(bcsp, skb->data, skb->len, skb->pkt_type); 289 struct sk_buff *nskb = bcsp_prepare_pkt(bcsp, skb->data, skb->len, bt_cb(skb)->pkt_type);
290 if (nskb) { 290 if (nskb) {
291 kfree_skb(skb); 291 kfree_skb(skb);
292 return nskb; 292 return nskb;
@@ -303,7 +303,7 @@ static struct sk_buff *bcsp_dequeue(struct hci_uart *hu)
303 spin_lock_irqsave(&bcsp->unack.lock, flags); 303 spin_lock_irqsave(&bcsp->unack.lock, flags);
304 304
305 if (bcsp->unack.qlen < BCSP_TXWINSIZE && (skb = skb_dequeue(&bcsp->rel)) != NULL) { 305 if (bcsp->unack.qlen < BCSP_TXWINSIZE && (skb = skb_dequeue(&bcsp->rel)) != NULL) {
306 struct sk_buff *nskb = bcsp_prepare_pkt(bcsp, skb->data, skb->len, skb->pkt_type); 306 struct sk_buff *nskb = bcsp_prepare_pkt(bcsp, skb->data, skb->len, bt_cb(skb)->pkt_type);
307 if (nskb) { 307 if (nskb) {
308 __skb_queue_tail(&bcsp->unack, skb); 308 __skb_queue_tail(&bcsp->unack, skb);
309 mod_timer(&bcsp->tbcsp, jiffies + HZ / 4); 309 mod_timer(&bcsp->tbcsp, jiffies + HZ / 4);
@@ -401,7 +401,7 @@ static void bcsp_handle_le_pkt(struct hci_uart *hu)
401 if (!nskb) 401 if (!nskb)
402 return; 402 return;
403 memcpy(skb_put(nskb, 4), conf_rsp_pkt, 4); 403 memcpy(skb_put(nskb, 4), conf_rsp_pkt, 4);
404 nskb->pkt_type = BCSP_LE_PKT; 404 bt_cb(nskb)->pkt_type = BCSP_LE_PKT;
405 405
406 skb_queue_head(&bcsp->unrel, nskb); 406 skb_queue_head(&bcsp->unrel, nskb);
407 hci_uart_tx_wakeup(hu); 407 hci_uart_tx_wakeup(hu);
@@ -483,14 +483,14 @@ static inline void bcsp_complete_rx_pkt(struct hci_uart *hu)
483 bcsp_pkt_cull(bcsp); 483 bcsp_pkt_cull(bcsp);
484 if ((bcsp->rx_skb->data[1] & 0x0f) == 6 && 484 if ((bcsp->rx_skb->data[1] & 0x0f) == 6 &&
485 bcsp->rx_skb->data[0] & 0x80) { 485 bcsp->rx_skb->data[0] & 0x80) {
486 bcsp->rx_skb->pkt_type = HCI_ACLDATA_PKT; 486 bt_cb(bcsp->rx_skb)->pkt_type = HCI_ACLDATA_PKT;
487 pass_up = 1; 487 pass_up = 1;
488 } else if ((bcsp->rx_skb->data[1] & 0x0f) == 5 && 488 } else if ((bcsp->rx_skb->data[1] & 0x0f) == 5 &&
489 bcsp->rx_skb->data[0] & 0x80) { 489 bcsp->rx_skb->data[0] & 0x80) {
490 bcsp->rx_skb->pkt_type = HCI_EVENT_PKT; 490 bt_cb(bcsp->rx_skb)->pkt_type = HCI_EVENT_PKT;
491 pass_up = 1; 491 pass_up = 1;
492 } else if ((bcsp->rx_skb->data[1] & 0x0f) == 7) { 492 } else if ((bcsp->rx_skb->data[1] & 0x0f) == 7) {
493 bcsp->rx_skb->pkt_type = HCI_SCODATA_PKT; 493 bt_cb(bcsp->rx_skb)->pkt_type = HCI_SCODATA_PKT;
494 pass_up = 1; 494 pass_up = 1;
495 } else if ((bcsp->rx_skb->data[1] & 0x0f) == 1 && 495 } else if ((bcsp->rx_skb->data[1] & 0x0f) == 1 &&
496 !(bcsp->rx_skb->data[0] & 0x80)) { 496 !(bcsp->rx_skb->data[0] & 0x80)) {
@@ -512,7 +512,7 @@ static inline void bcsp_complete_rx_pkt(struct hci_uart *hu)
512 hdr.evt = 0xff; 512 hdr.evt = 0xff;
513 hdr.plen = bcsp->rx_skb->len; 513 hdr.plen = bcsp->rx_skb->len;
514 memcpy(skb_push(bcsp->rx_skb, HCI_EVENT_HDR_SIZE), &hdr, HCI_EVENT_HDR_SIZE); 514 memcpy(skb_push(bcsp->rx_skb, HCI_EVENT_HDR_SIZE), &hdr, HCI_EVENT_HDR_SIZE);
515 bcsp->rx_skb->pkt_type = HCI_EVENT_PKT; 515 bt_cb(bcsp->rx_skb)->pkt_type = HCI_EVENT_PKT;
516 516
517 hci_recv_frame(bcsp->rx_skb); 517 hci_recv_frame(bcsp->rx_skb);
518 } else { 518 } else {
diff --git a/drivers/bluetooth/hci_h4.c b/drivers/bluetooth/hci_h4.c
index 533323b60e63..cf8a22d58d96 100644
--- a/drivers/bluetooth/hci_h4.c
+++ b/drivers/bluetooth/hci_h4.c
@@ -112,7 +112,7 @@ static int h4_enqueue(struct hci_uart *hu, struct sk_buff *skb)
112 BT_DBG("hu %p skb %p", hu, skb); 112 BT_DBG("hu %p skb %p", hu, skb);
113 113
114 /* Prepend skb with frame type */ 114 /* Prepend skb with frame type */
115 memcpy(skb_push(skb, 1), &skb->pkt_type, 1); 115 memcpy(skb_push(skb, 1), &bt_cb(skb)->pkt_type, 1);
116 skb_queue_tail(&h4->txq, skb); 116 skb_queue_tail(&h4->txq, skb);
117 return 0; 117 return 0;
118} 118}
@@ -239,7 +239,7 @@ static int h4_recv(struct hci_uart *hu, void *data, int count)
239 return 0; 239 return 0;
240 } 240 }
241 h4->rx_skb->dev = (void *) hu->hdev; 241 h4->rx_skb->dev = (void *) hu->hdev;
242 h4->rx_skb->pkt_type = type; 242 bt_cb(h4->rx_skb)->pkt_type = type;
243 } 243 }
244 return count; 244 return count;
245} 245}
diff --git a/drivers/bluetooth/hci_ldisc.c b/drivers/bluetooth/hci_ldisc.c
index 90be2eae52e0..aed80cc22890 100644
--- a/drivers/bluetooth/hci_ldisc.c
+++ b/drivers/bluetooth/hci_ldisc.c
@@ -153,7 +153,7 @@ restart:
153 break; 153 break;
154 } 154 }
155 155
156 hci_uart_tx_complete(hu, skb->pkt_type); 156 hci_uart_tx_complete(hu, bt_cb(skb)->pkt_type);
157 kfree_skb(skb); 157 kfree_skb(skb);
158 } 158 }
159 159
@@ -229,7 +229,7 @@ static int hci_uart_send_frame(struct sk_buff *skb)
229 hu = (struct hci_uart *) hdev->driver_data; 229 hu = (struct hci_uart *) hdev->driver_data;
230 tty = hu->tty; 230 tty = hu->tty;
231 231
232 BT_DBG("%s: type %d len %d", hdev->name, skb->pkt_type, skb->len); 232 BT_DBG("%s: type %d len %d", hdev->name, bt_cb(skb)->pkt_type, skb->len);
233 233
234 hu->proto->enqueue(hu, skb); 234 hu->proto->enqueue(hu, skb);
235 235
diff --git a/drivers/bluetooth/hci_usb.c b/drivers/bluetooth/hci_usb.c
index 657719b8254f..67d96b5cbb96 100644
--- a/drivers/bluetooth/hci_usb.c
+++ b/drivers/bluetooth/hci_usb.c
@@ -127,7 +127,7 @@ static struct usb_device_id blacklist_ids[] = {
127 { } /* Terminating entry */ 127 { } /* Terminating entry */
128}; 128};
129 129
130static struct _urb *_urb_alloc(int isoc, int gfp) 130static struct _urb *_urb_alloc(int isoc, unsigned int __nocast gfp)
131{ 131{
132 struct _urb *_urb = kmalloc(sizeof(struct _urb) + 132 struct _urb *_urb = kmalloc(sizeof(struct _urb) +
133 sizeof(struct usb_iso_packet_descriptor) * isoc, gfp); 133 sizeof(struct usb_iso_packet_descriptor) * isoc, gfp);
@@ -443,7 +443,7 @@ static int __tx_submit(struct hci_usb *husb, struct _urb *_urb)
443 443
444static inline int hci_usb_send_ctrl(struct hci_usb *husb, struct sk_buff *skb) 444static inline int hci_usb_send_ctrl(struct hci_usb *husb, struct sk_buff *skb)
445{ 445{
446 struct _urb *_urb = __get_completed(husb, skb->pkt_type); 446 struct _urb *_urb = __get_completed(husb, bt_cb(skb)->pkt_type);
447 struct usb_ctrlrequest *dr; 447 struct usb_ctrlrequest *dr;
448 struct urb *urb; 448 struct urb *urb;
449 449
@@ -451,7 +451,7 @@ static inline int hci_usb_send_ctrl(struct hci_usb *husb, struct sk_buff *skb)
451 _urb = _urb_alloc(0, GFP_ATOMIC); 451 _urb = _urb_alloc(0, GFP_ATOMIC);
452 if (!_urb) 452 if (!_urb)
453 return -ENOMEM; 453 return -ENOMEM;
454 _urb->type = skb->pkt_type; 454 _urb->type = bt_cb(skb)->pkt_type;
455 455
456 dr = kmalloc(sizeof(*dr), GFP_ATOMIC); 456 dr = kmalloc(sizeof(*dr), GFP_ATOMIC);
457 if (!dr) { 457 if (!dr) {
@@ -479,7 +479,7 @@ static inline int hci_usb_send_ctrl(struct hci_usb *husb, struct sk_buff *skb)
479 479
480static inline int hci_usb_send_bulk(struct hci_usb *husb, struct sk_buff *skb) 480static inline int hci_usb_send_bulk(struct hci_usb *husb, struct sk_buff *skb)
481{ 481{
482 struct _urb *_urb = __get_completed(husb, skb->pkt_type); 482 struct _urb *_urb = __get_completed(husb, bt_cb(skb)->pkt_type);
483 struct urb *urb; 483 struct urb *urb;
484 int pipe; 484 int pipe;
485 485
@@ -487,7 +487,7 @@ static inline int hci_usb_send_bulk(struct hci_usb *husb, struct sk_buff *skb)
487 _urb = _urb_alloc(0, GFP_ATOMIC); 487 _urb = _urb_alloc(0, GFP_ATOMIC);
488 if (!_urb) 488 if (!_urb)
489 return -ENOMEM; 489 return -ENOMEM;
490 _urb->type = skb->pkt_type; 490 _urb->type = bt_cb(skb)->pkt_type;
491 } 491 }
492 492
493 urb = &_urb->urb; 493 urb = &_urb->urb;
@@ -505,14 +505,14 @@ static inline int hci_usb_send_bulk(struct hci_usb *husb, struct sk_buff *skb)
505#ifdef CONFIG_BT_HCIUSB_SCO 505#ifdef CONFIG_BT_HCIUSB_SCO
506static inline int hci_usb_send_isoc(struct hci_usb *husb, struct sk_buff *skb) 506static inline int hci_usb_send_isoc(struct hci_usb *husb, struct sk_buff *skb)
507{ 507{
508 struct _urb *_urb = __get_completed(husb, skb->pkt_type); 508 struct _urb *_urb = __get_completed(husb, bt_cb(skb)->pkt_type);
509 struct urb *urb; 509 struct urb *urb;
510 510
511 if (!_urb) { 511 if (!_urb) {
512 _urb = _urb_alloc(HCI_MAX_ISOC_FRAMES, GFP_ATOMIC); 512 _urb = _urb_alloc(HCI_MAX_ISOC_FRAMES, GFP_ATOMIC);
513 if (!_urb) 513 if (!_urb)
514 return -ENOMEM; 514 return -ENOMEM;
515 _urb->type = skb->pkt_type; 515 _urb->type = bt_cb(skb)->pkt_type;
516 } 516 }
517 517
518 BT_DBG("%s skb %p len %d", husb->hdev->name, skb, skb->len); 518 BT_DBG("%s skb %p len %d", husb->hdev->name, skb, skb->len);
@@ -601,11 +601,11 @@ static int hci_usb_send_frame(struct sk_buff *skb)
601 if (!test_bit(HCI_RUNNING, &hdev->flags)) 601 if (!test_bit(HCI_RUNNING, &hdev->flags))
602 return -EBUSY; 602 return -EBUSY;
603 603
604 BT_DBG("%s type %d len %d", hdev->name, skb->pkt_type, skb->len); 604 BT_DBG("%s type %d len %d", hdev->name, bt_cb(skb)->pkt_type, skb->len);
605 605
606 husb = (struct hci_usb *) hdev->driver_data; 606 husb = (struct hci_usb *) hdev->driver_data;
607 607
608 switch (skb->pkt_type) { 608 switch (bt_cb(skb)->pkt_type) {
609 case HCI_COMMAND_PKT: 609 case HCI_COMMAND_PKT:
610 hdev->stat.cmd_tx++; 610 hdev->stat.cmd_tx++;
611 break; 611 break;
@@ -627,7 +627,7 @@ static int hci_usb_send_frame(struct sk_buff *skb)
627 627
628 read_lock(&husb->completion_lock); 628 read_lock(&husb->completion_lock);
629 629
630 skb_queue_tail(__transmit_q(husb, skb->pkt_type), skb); 630 skb_queue_tail(__transmit_q(husb, bt_cb(skb)->pkt_type), skb);
631 hci_usb_tx_wakeup(husb); 631 hci_usb_tx_wakeup(husb);
632 632
633 read_unlock(&husb->completion_lock); 633 read_unlock(&husb->completion_lock);
@@ -682,7 +682,7 @@ static inline int __recv_frame(struct hci_usb *husb, int type, void *data, int c
682 return -ENOMEM; 682 return -ENOMEM;
683 } 683 }
684 skb->dev = (void *) husb->hdev; 684 skb->dev = (void *) husb->hdev;
685 skb->pkt_type = type; 685 bt_cb(skb)->pkt_type = type;
686 686
687 __reassembly(husb, type) = skb; 687 __reassembly(husb, type) = skb;
688 688
@@ -702,6 +702,7 @@ static inline int __recv_frame(struct hci_usb *husb, int type, void *data, int c
702 if (!scb->expect) { 702 if (!scb->expect) {
703 /* Complete frame */ 703 /* Complete frame */
704 __reassembly(husb, type) = NULL; 704 __reassembly(husb, type) = NULL;
705 bt_cb(skb)->pkt_type = type;
705 hci_recv_frame(skb); 706 hci_recv_frame(skb);
706 } 707 }
707 708
diff --git a/drivers/bluetooth/hci_vhci.c b/drivers/bluetooth/hci_vhci.c
index f9b956fb2b8b..52cbd45c308f 100644
--- a/drivers/bluetooth/hci_vhci.c
+++ b/drivers/bluetooth/hci_vhci.c
@@ -1,229 +1,220 @@
1/*
2 BlueZ - Bluetooth protocol stack for Linux
3 Copyright (C) 2000-2001 Qualcomm Incorporated
4
5 Written 2000,2001 by Maxim Krasnyansky <maxk@qualcomm.com>
6
7 This program is free software; you can redistribute it and/or modify
8 it under the terms of the GNU General Public License version 2 as
9 published by the Free Software Foundation;
10
11 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
12 OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
13 FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF THIRD PARTY RIGHTS.
14 IN NO EVENT SHALL THE COPYRIGHT HOLDER(S) AND AUTHOR(S) BE LIABLE FOR ANY
15 CLAIM, OR ANY SPECIAL INDIRECT OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES
16 WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
17 ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
18 OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
19
20 ALL LIABILITY, INCLUDING LIABILITY FOR INFRINGEMENT OF ANY PATENTS,
21 COPYRIGHTS, TRADEMARKS OR OTHER RIGHTS, RELATING TO USE OF THIS
22 SOFTWARE IS DISCLAIMED.
23*/
24
25/* 1/*
26 * Bluetooth HCI virtual device driver.
27 * 2 *
28 * $Id: hci_vhci.c,v 1.3 2002/04/17 17:37:20 maxk Exp $ 3 * Bluetooth virtual HCI driver
4 *
5 * Copyright (C) 2000-2001 Qualcomm Incorporated
6 * Copyright (C) 2002-2003 Maxim Krasnyansky <maxk@qualcomm.com>
7 * Copyright (C) 2004-2005 Marcel Holtmann <marcel@holtmann.org>
8 *
9 *
10 * This program is free software; you can redistribute it and/or modify
11 * it under the terms of the GNU General Public License as published by
12 * the Free Software Foundation; either version 2 of the License, or
13 * (at your option) any later version.
14 *
15 * This program is distributed in the hope that it will be useful,
16 * but WITHOUT ANY WARRANTY; without even the implied warranty of
17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 * GNU General Public License for more details.
19 *
20 * You should have received a copy of the GNU General Public License
21 * along with this program; if not, write to the Free Software
22 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
23 *
29 */ 24 */
30#define VERSION "1.1"
31 25
32#include <linux/config.h> 26#include <linux/config.h>
33#include <linux/module.h> 27#include <linux/module.h>
34 28
35#include <linux/errno.h>
36#include <linux/kernel.h> 29#include <linux/kernel.h>
37#include <linux/major.h> 30#include <linux/init.h>
38#include <linux/sched.h>
39#include <linux/slab.h> 31#include <linux/slab.h>
32#include <linux/types.h>
33#include <linux/errno.h>
34#include <linux/sched.h>
40#include <linux/poll.h> 35#include <linux/poll.h>
41#include <linux/fcntl.h>
42#include <linux/init.h>
43#include <linux/random.h>
44 36
45#include <linux/skbuff.h> 37#include <linux/skbuff.h>
46#include <linux/miscdevice.h> 38#include <linux/miscdevice.h>
47 39
48#include <asm/system.h>
49#include <asm/uaccess.h>
50
51#include <net/bluetooth/bluetooth.h> 40#include <net/bluetooth/bluetooth.h>
52#include <net/bluetooth/hci_core.h> 41#include <net/bluetooth/hci_core.h>
53#include "hci_vhci.h"
54 42
55/* HCI device part */ 43#ifndef CONFIG_BT_HCIVHCI_DEBUG
44#undef BT_DBG
45#define BT_DBG(D...)
46#endif
47
48#define VERSION "1.2"
49
50static int minor = MISC_DYNAMIC_MINOR;
51
52struct vhci_data {
53 struct hci_dev *hdev;
54
55 unsigned long flags;
56
57 wait_queue_head_t read_wait;
58 struct sk_buff_head readq;
59
60 struct fasync_struct *fasync;
61};
56 62
57static int hci_vhci_open(struct hci_dev *hdev) 63#define VHCI_FASYNC 0x0010
64
65static struct miscdevice vhci_miscdev;
66
67static int vhci_open_dev(struct hci_dev *hdev)
58{ 68{
59 set_bit(HCI_RUNNING, &hdev->flags); 69 set_bit(HCI_RUNNING, &hdev->flags);
60 return 0;
61}
62 70
63static int hci_vhci_flush(struct hci_dev *hdev)
64{
65 struct hci_vhci_struct *hci_vhci = (struct hci_vhci_struct *) hdev->driver_data;
66 skb_queue_purge(&hci_vhci->readq);
67 return 0; 71 return 0;
68} 72}
69 73
70static int hci_vhci_close(struct hci_dev *hdev) 74static int vhci_close_dev(struct hci_dev *hdev)
71{ 75{
76 struct vhci_data *vhci = hdev->driver_data;
77
72 if (!test_and_clear_bit(HCI_RUNNING, &hdev->flags)) 78 if (!test_and_clear_bit(HCI_RUNNING, &hdev->flags))
73 return 0; 79 return 0;
74 80
75 hci_vhci_flush(hdev); 81 skb_queue_purge(&vhci->readq);
82
76 return 0; 83 return 0;
77} 84}
78 85
79static void hci_vhci_destruct(struct hci_dev *hdev) 86static int vhci_flush(struct hci_dev *hdev)
80{ 87{
81 struct hci_vhci_struct *vhci; 88 struct vhci_data *vhci = hdev->driver_data;
82 89
83 if (!hdev) return; 90 skb_queue_purge(&vhci->readq);
84 91
85 vhci = (struct hci_vhci_struct *) hdev->driver_data; 92 return 0;
86 kfree(vhci);
87} 93}
88 94
89static int hci_vhci_send_frame(struct sk_buff *skb) 95static int vhci_send_frame(struct sk_buff *skb)
90{ 96{
91 struct hci_dev* hdev = (struct hci_dev *) skb->dev; 97 struct hci_dev* hdev = (struct hci_dev *) skb->dev;
92 struct hci_vhci_struct *hci_vhci; 98 struct vhci_data *vhci;
93 99
94 if (!hdev) { 100 if (!hdev) {
95 BT_ERR("Frame for uknown device (hdev=NULL)"); 101 BT_ERR("Frame for unknown HCI device (hdev=NULL)");
96 return -ENODEV; 102 return -ENODEV;
97 } 103 }
98 104
99 if (!test_bit(HCI_RUNNING, &hdev->flags)) 105 if (!test_bit(HCI_RUNNING, &hdev->flags))
100 return -EBUSY; 106 return -EBUSY;
101 107
102 hci_vhci = (struct hci_vhci_struct *) hdev->driver_data; 108 vhci = hdev->driver_data;
109
110 memcpy(skb_push(skb, 1), &bt_cb(skb)->pkt_type, 1);
111 skb_queue_tail(&vhci->readq, skb);
103 112
104 memcpy(skb_push(skb, 1), &skb->pkt_type, 1); 113 if (vhci->flags & VHCI_FASYNC)
105 skb_queue_tail(&hci_vhci->readq, skb); 114 kill_fasync(&vhci->fasync, SIGIO, POLL_IN);
106 115
107 if (hci_vhci->flags & VHCI_FASYNC) 116 wake_up_interruptible(&vhci->read_wait);
108 kill_fasync(&hci_vhci->fasync, SIGIO, POLL_IN);
109 wake_up_interruptible(&hci_vhci->read_wait);
110 117
111 return 0; 118 return 0;
112} 119}
113 120
114/* Character device part */ 121static void vhci_destruct(struct hci_dev *hdev)
115 122{
116/* Poll */ 123 kfree(hdev->driver_data);
117static unsigned int hci_vhci_chr_poll(struct file *file, poll_table * wait)
118{
119 struct hci_vhci_struct *hci_vhci = (struct hci_vhci_struct *) file->private_data;
120
121 poll_wait(file, &hci_vhci->read_wait, wait);
122
123 if (!skb_queue_empty(&hci_vhci->readq))
124 return POLLIN | POLLRDNORM;
125
126 return POLLOUT | POLLWRNORM;
127} 124}
128 125
129/* Get packet from user space buffer(already verified) */ 126static inline ssize_t vhci_get_user(struct vhci_data *vhci,
130static inline ssize_t hci_vhci_get_user(struct hci_vhci_struct *hci_vhci, const char __user *buf, size_t count) 127 const char __user *buf, size_t count)
131{ 128{
132 struct sk_buff *skb; 129 struct sk_buff *skb;
133 130
134 if (count > HCI_MAX_FRAME_SIZE) 131 if (count > HCI_MAX_FRAME_SIZE)
135 return -EINVAL; 132 return -EINVAL;
136 133
137 if (!(skb = bt_skb_alloc(count, GFP_KERNEL))) 134 skb = bt_skb_alloc(count, GFP_KERNEL);
135 if (!skb)
138 return -ENOMEM; 136 return -ENOMEM;
139 137
140 if (copy_from_user(skb_put(skb, count), buf, count)) { 138 if (copy_from_user(skb_put(skb, count), buf, count)) {
141 kfree_skb(skb); 139 kfree_skb(skb);
142 return -EFAULT; 140 return -EFAULT;
143 } 141 }
144 142
145 skb->dev = (void *) hci_vhci->hdev; 143 skb->dev = (void *) vhci->hdev;
146 skb->pkt_type = *((__u8 *) skb->data); 144 bt_cb(skb)->pkt_type = *((__u8 *) skb->data);
147 skb_pull(skb, 1); 145 skb_pull(skb, 1);
148 146
149 hci_recv_frame(skb); 147 hci_recv_frame(skb);
150 148
151 return count; 149 return count;
152}
153
154/* Write */
155static ssize_t hci_vhci_chr_write(struct file * file, const char __user * buf,
156 size_t count, loff_t *pos)
157{
158 struct hci_vhci_struct *hci_vhci = (struct hci_vhci_struct *) file->private_data;
159
160 if (!access_ok(VERIFY_READ, buf, count))
161 return -EFAULT;
162
163 return hci_vhci_get_user(hci_vhci, buf, count);
164} 150}
165 151
166/* Put packet to user space buffer(already verified) */ 152static inline ssize_t vhci_put_user(struct vhci_data *vhci,
167static inline ssize_t hci_vhci_put_user(struct hci_vhci_struct *hci_vhci, 153 struct sk_buff *skb, char __user *buf, int count)
168 struct sk_buff *skb, char __user *buf,
169 int count)
170{ 154{
171 int len = count, total = 0;
172 char __user *ptr = buf; 155 char __user *ptr = buf;
156 int len, total = 0;
157
158 len = min_t(unsigned int, skb->len, count);
173 159
174 len = min_t(unsigned int, skb->len, len);
175 if (copy_to_user(ptr, skb->data, len)) 160 if (copy_to_user(ptr, skb->data, len))
176 return -EFAULT; 161 return -EFAULT;
162
177 total += len; 163 total += len;
178 164
179 hci_vhci->hdev->stat.byte_tx += len; 165 vhci->hdev->stat.byte_tx += len;
180 switch (skb->pkt_type) {
181 case HCI_COMMAND_PKT:
182 hci_vhci->hdev->stat.cmd_tx++;
183 break;
184 166
185 case HCI_ACLDATA_PKT: 167 switch (bt_cb(skb)->pkt_type) {
186 hci_vhci->hdev->stat.acl_tx++; 168 case HCI_COMMAND_PKT:
187 break; 169 vhci->hdev->stat.cmd_tx++;
170 break;
171
172 case HCI_ACLDATA_PKT:
173 vhci->hdev->stat.acl_tx++;
174 break;
188 175
189 case HCI_SCODATA_PKT: 176 case HCI_SCODATA_PKT:
190 hci_vhci->hdev->stat.cmd_tx++; 177 vhci->hdev->stat.cmd_tx++;
191 break; 178 break;
192 }; 179 };
193 180
194 return total; 181 return total;
195} 182}
196 183
197/* Read */ 184static loff_t vhci_llseek(struct file * file, loff_t offset, int origin)
198static ssize_t hci_vhci_chr_read(struct file * file, char __user * buf, size_t count, loff_t *pos) 185{
186 return -ESPIPE;
187}
188
189static ssize_t vhci_read(struct file * file, char __user * buf, size_t count, loff_t *pos)
199{ 190{
200 struct hci_vhci_struct *hci_vhci = (struct hci_vhci_struct *) file->private_data;
201 DECLARE_WAITQUEUE(wait, current); 191 DECLARE_WAITQUEUE(wait, current);
192 struct vhci_data *vhci = file->private_data;
202 struct sk_buff *skb; 193 struct sk_buff *skb;
203 ssize_t ret = 0; 194 ssize_t ret = 0;
204 195
205 add_wait_queue(&hci_vhci->read_wait, &wait); 196 add_wait_queue(&vhci->read_wait, &wait);
206 while (count) { 197 while (count) {
207 set_current_state(TASK_INTERRUPTIBLE); 198 set_current_state(TASK_INTERRUPTIBLE);
208 199
209 /* Read frames from device queue */ 200 skb = skb_dequeue(&vhci->readq);
210 if (!(skb = skb_dequeue(&hci_vhci->readq))) { 201 if (!skb) {
211 if (file->f_flags & O_NONBLOCK) { 202 if (file->f_flags & O_NONBLOCK) {
212 ret = -EAGAIN; 203 ret = -EAGAIN;
213 break; 204 break;
214 } 205 }
206
215 if (signal_pending(current)) { 207 if (signal_pending(current)) {
216 ret = -ERESTARTSYS; 208 ret = -ERESTARTSYS;
217 break; 209 break;
218 } 210 }
219 211
220 /* Nothing to read, let's sleep */
221 schedule(); 212 schedule();
222 continue; 213 continue;
223 } 214 }
224 215
225 if (access_ok(VERIFY_WRITE, buf, count)) 216 if (access_ok(VERIFY_WRITE, buf, count))
226 ret = hci_vhci_put_user(hci_vhci, skb, buf, count); 217 ret = vhci_put_user(vhci, skb, buf, count);
227 else 218 else
228 ret = -EFAULT; 219 ret = -EFAULT;
229 220
@@ -231,84 +222,90 @@ static ssize_t hci_vhci_chr_read(struct file * file, char __user * buf, size_t c
231 break; 222 break;
232 } 223 }
233 set_current_state(TASK_RUNNING); 224 set_current_state(TASK_RUNNING);
234 remove_wait_queue(&hci_vhci->read_wait, &wait); 225 remove_wait_queue(&vhci->read_wait, &wait);
235 226
236 return ret; 227 return ret;
237} 228}
238 229
239static loff_t hci_vhci_chr_lseek(struct file * file, loff_t offset, int origin) 230static ssize_t vhci_write(struct file *file,
231 const char __user *buf, size_t count, loff_t *pos)
240{ 232{
241 return -ESPIPE; 233 struct vhci_data *vhci = file->private_data;
242}
243 234
244static int hci_vhci_chr_ioctl(struct inode *inode, struct file *file, unsigned int cmd, unsigned long arg) 235 if (!access_ok(VERIFY_READ, buf, count))
245{ 236 return -EFAULT;
246 return -EINVAL; 237
238 return vhci_get_user(vhci, buf, count);
247} 239}
248 240
249static int hci_vhci_chr_fasync(int fd, struct file *file, int on) 241static unsigned int vhci_poll(struct file *file, poll_table *wait)
250{ 242{
251 struct hci_vhci_struct *hci_vhci = (struct hci_vhci_struct *) file->private_data; 243 struct vhci_data *vhci = file->private_data;
252 int ret;
253 244
254 if ((ret = fasync_helper(fd, file, on, &hci_vhci->fasync)) < 0) 245 poll_wait(file, &vhci->read_wait, wait);
255 return ret;
256
257 if (on)
258 hci_vhci->flags |= VHCI_FASYNC;
259 else
260 hci_vhci->flags &= ~VHCI_FASYNC;
261 246
262 return 0; 247 if (!skb_queue_empty(&vhci->readq))
248 return POLLIN | POLLRDNORM;
249
250 return POLLOUT | POLLWRNORM;
263} 251}
264 252
265static int hci_vhci_chr_open(struct inode *inode, struct file * file) 253static int vhci_ioctl(struct inode *inode, struct file *file,
254 unsigned int cmd, unsigned long arg)
266{ 255{
267 struct hci_vhci_struct *hci_vhci = NULL; 256 return -EINVAL;
257}
258
259static int vhci_open(struct inode *inode, struct file *file)
260{
261 struct vhci_data *vhci;
268 struct hci_dev *hdev; 262 struct hci_dev *hdev;
269 263
270 if (!(hci_vhci = kmalloc(sizeof(struct hci_vhci_struct), GFP_KERNEL))) 264 vhci = kmalloc(sizeof(struct vhci_data), GFP_KERNEL);
265 if (!vhci)
271 return -ENOMEM; 266 return -ENOMEM;
272 267
273 memset(hci_vhci, 0, sizeof(struct hci_vhci_struct)); 268 memset(vhci, 0, sizeof(struct vhci_data));
274 269
275 skb_queue_head_init(&hci_vhci->readq); 270 skb_queue_head_init(&vhci->readq);
276 init_waitqueue_head(&hci_vhci->read_wait); 271 init_waitqueue_head(&vhci->read_wait);
277 272
278 /* Initialize and register HCI device */
279 hdev = hci_alloc_dev(); 273 hdev = hci_alloc_dev();
280 if (!hdev) { 274 if (!hdev) {
281 kfree(hci_vhci); 275 kfree(vhci);
282 return -ENOMEM; 276 return -ENOMEM;
283 } 277 }
284 278
285 hci_vhci->hdev = hdev; 279 vhci->hdev = hdev;
286 280
287 hdev->type = HCI_VHCI; 281 hdev->type = HCI_VHCI;
288 hdev->driver_data = hci_vhci; 282 hdev->driver_data = vhci;
283 SET_HCIDEV_DEV(hdev, vhci_miscdev.dev);
289 284
290 hdev->open = hci_vhci_open; 285 hdev->open = vhci_open_dev;
291 hdev->close = hci_vhci_close; 286 hdev->close = vhci_close_dev;
292 hdev->flush = hci_vhci_flush; 287 hdev->flush = vhci_flush;
293 hdev->send = hci_vhci_send_frame; 288 hdev->send = vhci_send_frame;
294 hdev->destruct = hci_vhci_destruct; 289 hdev->destruct = vhci_destruct;
295 290
296 hdev->owner = THIS_MODULE; 291 hdev->owner = THIS_MODULE;
297 292
298 if (hci_register_dev(hdev) < 0) { 293 if (hci_register_dev(hdev) < 0) {
299 kfree(hci_vhci); 294 BT_ERR("Can't register HCI device");
295 kfree(vhci);
300 hci_free_dev(hdev); 296 hci_free_dev(hdev);
301 return -EBUSY; 297 return -EBUSY;
302 } 298 }
303 299
304 file->private_data = hci_vhci; 300 file->private_data = vhci;
305 return nonseekable_open(inode, file); 301
302 return nonseekable_open(inode, file);
306} 303}
307 304
308static int hci_vhci_chr_close(struct inode *inode, struct file *file) 305static int vhci_release(struct inode *inode, struct file *file)
309{ 306{
310 struct hci_vhci_struct *hci_vhci = (struct hci_vhci_struct *) file->private_data; 307 struct vhci_data *vhci = file->private_data;
311 struct hci_dev *hdev = hci_vhci->hdev; 308 struct hci_dev *hdev = vhci->hdev;
312 309
313 if (hci_unregister_dev(hdev) < 0) { 310 if (hci_unregister_dev(hdev) < 0) {
314 BT_ERR("Can't unregister HCI device %s", hdev->name); 311 BT_ERR("Can't unregister HCI device %s", hdev->name);
@@ -317,48 +314,71 @@ static int hci_vhci_chr_close(struct inode *inode, struct file *file)
317 hci_free_dev(hdev); 314 hci_free_dev(hdev);
318 315
319 file->private_data = NULL; 316 file->private_data = NULL;
317
320 return 0; 318 return 0;
321} 319}
322 320
323static struct file_operations hci_vhci_fops = { 321static int vhci_fasync(int fd, struct file *file, int on)
324 .owner = THIS_MODULE, 322{
325 .llseek = hci_vhci_chr_lseek, 323 struct vhci_data *vhci = file->private_data;
326 .read = hci_vhci_chr_read, 324 int err;
327 .write = hci_vhci_chr_write, 325
328 .poll = hci_vhci_chr_poll, 326 err = fasync_helper(fd, file, on, &vhci->fasync);
329 .ioctl = hci_vhci_chr_ioctl, 327 if (err < 0)
330 .open = hci_vhci_chr_open, 328 return err;
331 .release = hci_vhci_chr_close, 329
332 .fasync = hci_vhci_chr_fasync 330 if (on)
331 vhci->flags |= VHCI_FASYNC;
332 else
333 vhci->flags &= ~VHCI_FASYNC;
334
335 return 0;
336}
337
338static struct file_operations vhci_fops = {
339 .owner = THIS_MODULE,
340 .llseek = vhci_llseek,
341 .read = vhci_read,
342 .write = vhci_write,
343 .poll = vhci_poll,
344 .ioctl = vhci_ioctl,
345 .open = vhci_open,
346 .release = vhci_release,
347 .fasync = vhci_fasync,
333}; 348};
334 349
335static struct miscdevice hci_vhci_miscdev= 350static struct miscdevice vhci_miscdev= {
336{ 351 .name = "vhci",
337 VHCI_MINOR, 352 .fops = &vhci_fops,
338 "hci_vhci",
339 &hci_vhci_fops
340}; 353};
341 354
342static int __init hci_vhci_init(void) 355static int __init vhci_init(void)
343{ 356{
344 BT_INFO("VHCI driver ver %s", VERSION); 357 BT_INFO("Virtual HCI driver ver %s", VERSION);
345 358
346 if (misc_register(&hci_vhci_miscdev)) { 359 vhci_miscdev.minor = minor;
347 BT_ERR("Can't register misc device %d\n", VHCI_MINOR); 360
361 if (misc_register(&vhci_miscdev) < 0) {
362 BT_ERR("Can't register misc device with minor %d", minor);
348 return -EIO; 363 return -EIO;
349 } 364 }
350 365
351 return 0; 366 return 0;
352} 367}
353 368
354static void hci_vhci_cleanup(void) 369static void __exit vhci_exit(void)
355{ 370{
356 misc_deregister(&hci_vhci_miscdev); 371 if (misc_deregister(&vhci_miscdev) < 0)
372 BT_ERR("Can't unregister misc device with minor %d", minor);
357} 373}
358 374
359module_init(hci_vhci_init); 375module_init(vhci_init);
360module_exit(hci_vhci_cleanup); 376module_exit(vhci_exit);
377
378module_param(minor, int, 0444);
379MODULE_PARM_DESC(minor, "Miscellaneous minor device number");
361 380
362MODULE_AUTHOR("Maxim Krasnyansky <maxk@qualcomm.com>"); 381MODULE_AUTHOR("Maxim Krasnyansky <maxk@qualcomm.com>, Marcel Holtmann <marcel@holtmann.org>");
363MODULE_DESCRIPTION("Bluetooth VHCI driver ver " VERSION); 382MODULE_DESCRIPTION("Bluetooth virtual HCI driver ver " VERSION);
364MODULE_LICENSE("GPL"); 383MODULE_VERSION(VERSION);
384MODULE_LICENSE("GPL");
diff --git a/drivers/bluetooth/hci_vhci.h b/drivers/bluetooth/hci_vhci.h
deleted file mode 100644
index 53b11f9ef76d..000000000000
--- a/drivers/bluetooth/hci_vhci.h
+++ /dev/null
@@ -1,50 +0,0 @@
1/*
2 BlueZ - Bluetooth protocol stack for Linux
3 Copyright (C) 2000-2001 Qualcomm Incorporated
4
5 Written 2000,2001 by Maxim Krasnyansky <maxk@qualcomm.com>
6
7 This program is free software; you can redistribute it and/or modify
8 it under the terms of the GNU General Public License version 2 as
9 published by the Free Software Foundation;
10
11 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
12 OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
13 FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF THIRD PARTY RIGHTS.
14 IN NO EVENT SHALL THE COPYRIGHT HOLDER(S) AND AUTHOR(S) BE LIABLE FOR ANY
15 CLAIM, OR ANY SPECIAL INDIRECT OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES
16 WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
17 ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
18 OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
19
20 ALL LIABILITY, INCLUDING LIABILITY FOR INFRINGEMENT OF ANY PATENTS,
21 COPYRIGHTS, TRADEMARKS OR OTHER RIGHTS, RELATING TO USE OF THIS
22 SOFTWARE IS DISCLAIMED.
23*/
24
25/*
26 * $Id: hci_vhci.h,v 1.1.1.1 2002/03/08 21:03:15 maxk Exp $
27 */
28
29#ifndef __HCI_VHCI_H
30#define __HCI_VHCI_H
31
32#ifdef __KERNEL__
33
34struct hci_vhci_struct {
35 struct hci_dev *hdev;
36 __u32 flags;
37 wait_queue_head_t read_wait;
38 struct sk_buff_head readq;
39 struct fasync_struct *fasync;
40};
41
42/* VHCI device flags */
43#define VHCI_FASYNC 0x0010
44
45#endif /* __KERNEL__ */
46
47#define VHCI_DEV "/dev/vhci"
48#define VHCI_MINOR 250
49
50#endif /* __HCI_VHCI_H */
diff --git a/drivers/cdrom/viocd.c b/drivers/cdrom/viocd.c
index 38dd9ffbe8bc..0829db58462f 100644
--- a/drivers/cdrom/viocd.c
+++ b/drivers/cdrom/viocd.c
@@ -734,7 +734,7 @@ static int viocd_remove(struct vio_dev *vdev)
734 */ 734 */
735static struct vio_device_id viocd_device_table[] __devinitdata = { 735static struct vio_device_id viocd_device_table[] __devinitdata = {
736 { "viocd", "" }, 736 { "viocd", "" },
737 { 0, } 737 { "", "" }
738}; 738};
739 739
740MODULE_DEVICE_TABLE(vio, viocd_device_table); 740MODULE_DEVICE_TABLE(vio, viocd_device_table);
diff --git a/drivers/char/drm/Kconfig b/drivers/char/drm/Kconfig
index 123417e43040..56ace9d5e2ae 100644
--- a/drivers/char/drm/Kconfig
+++ b/drivers/char/drm/Kconfig
@@ -23,13 +23,6 @@ config DRM_TDFX
23 Choose this option if you have a 3dfx Banshee or Voodoo3 (or later), 23 Choose this option if you have a 3dfx Banshee or Voodoo3 (or later),
24 graphics card. If M is selected, the module will be called tdfx. 24 graphics card. If M is selected, the module will be called tdfx.
25 25
26config DRM_GAMMA
27 tristate "3dlabs GMX 2000"
28 depends on DRM && BROKEN
29 help
30 This is the old gamma driver, please tell me if it might actually
31 work.
32
33config DRM_R128 26config DRM_R128
34 tristate "ATI Rage 128" 27 tristate "ATI Rage 128"
35 depends on DRM && PCI 28 depends on DRM && PCI
@@ -82,7 +75,7 @@ endchoice
82 75
83config DRM_MGA 76config DRM_MGA
84 tristate "Matrox g200/g400" 77 tristate "Matrox g200/g400"
85 depends on DRM && AGP 78 depends on DRM
86 help 79 help
87 Choose this option if you have a Matrox G200, G400 or G450 graphics 80 Choose this option if you have a Matrox G200, G400 or G450 graphics
88 card. If M is selected, the module will be called mga. AGP 81 card. If M is selected, the module will be called mga. AGP
@@ -103,3 +96,10 @@ config DRM_VIA
103 Choose this option if you have a Via unichrome or compatible video 96 Choose this option if you have a Via unichrome or compatible video
104 chipset. If M is selected the module will be called via. 97 chipset. If M is selected the module will be called via.
105 98
99config DRM_SAVAGE
100 tristate "Savage video cards"
101 depends on DRM
102 help
103 Choose this option if you have a Savage3D/4/SuperSavage/Pro/Twister
104 chipset. If M is selected the module will be called savage.
105
diff --git a/drivers/char/drm/Makefile b/drivers/char/drm/Makefile
index ddd941045b1f..e41060c76226 100644
--- a/drivers/char/drm/Makefile
+++ b/drivers/char/drm/Makefile
@@ -8,16 +8,16 @@ drm-objs := drm_auth.o drm_bufs.o drm_context.o drm_dma.o drm_drawable.o \
8 drm_agpsupport.o drm_scatter.o ati_pcigart.o drm_pci.o \ 8 drm_agpsupport.o drm_scatter.o ati_pcigart.o drm_pci.o \
9 drm_sysfs.o 9 drm_sysfs.o
10 10
11gamma-objs := gamma_drv.o gamma_dma.o
12tdfx-objs := tdfx_drv.o 11tdfx-objs := tdfx_drv.o
13r128-objs := r128_drv.o r128_cce.o r128_state.o r128_irq.o 12r128-objs := r128_drv.o r128_cce.o r128_state.o r128_irq.o
14mga-objs := mga_drv.o mga_dma.o mga_state.o mga_warp.o mga_irq.o 13mga-objs := mga_drv.o mga_dma.o mga_state.o mga_warp.o mga_irq.o
15i810-objs := i810_drv.o i810_dma.o 14i810-objs := i810_drv.o i810_dma.o
16i830-objs := i830_drv.o i830_dma.o i830_irq.o 15i830-objs := i830_drv.o i830_dma.o i830_irq.o
17i915-objs := i915_drv.o i915_dma.o i915_irq.o i915_mem.o 16i915-objs := i915_drv.o i915_dma.o i915_irq.o i915_mem.o
18radeon-objs := radeon_drv.o radeon_cp.o radeon_state.o radeon_mem.o radeon_irq.o 17radeon-objs := radeon_drv.o radeon_cp.o radeon_state.o radeon_mem.o radeon_irq.o r300_cmdbuf.o
19ffb-objs := ffb_drv.o ffb_context.o 18ffb-objs := ffb_drv.o ffb_context.o
20sis-objs := sis_drv.o sis_ds.o sis_mm.o 19sis-objs := sis_drv.o sis_ds.o sis_mm.o
20savage-objs := savage_drv.o savage_bci.o savage_state.o
21via-objs := via_irq.o via_drv.o via_ds.o via_map.o via_mm.o via_dma.o via_verifier.o via_video.o 21via-objs := via_irq.o via_drv.o via_ds.o via_map.o via_mm.o via_dma.o via_verifier.o via_video.o
22 22
23ifeq ($(CONFIG_COMPAT),y) 23ifeq ($(CONFIG_COMPAT),y)
@@ -29,7 +29,6 @@ i915-objs += i915_ioc32.o
29endif 29endif
30 30
31obj-$(CONFIG_DRM) += drm.o 31obj-$(CONFIG_DRM) += drm.o
32obj-$(CONFIG_DRM_GAMMA) += gamma.o
33obj-$(CONFIG_DRM_TDFX) += tdfx.o 32obj-$(CONFIG_DRM_TDFX) += tdfx.o
34obj-$(CONFIG_DRM_R128) += r128.o 33obj-$(CONFIG_DRM_R128) += r128.o
35obj-$(CONFIG_DRM_RADEON)+= radeon.o 34obj-$(CONFIG_DRM_RADEON)+= radeon.o
@@ -39,5 +38,7 @@ obj-$(CONFIG_DRM_I830) += i830.o
39obj-$(CONFIG_DRM_I915) += i915.o 38obj-$(CONFIG_DRM_I915) += i915.o
40obj-$(CONFIG_DRM_FFB) += ffb.o 39obj-$(CONFIG_DRM_FFB) += ffb.o
41obj-$(CONFIG_DRM_SIS) += sis.o 40obj-$(CONFIG_DRM_SIS) += sis.o
41obj-$(CONFIG_DRM_SAVAGE)+= savage.o
42obj-$(CONFIG_DRM_VIA) +=via.o 42obj-$(CONFIG_DRM_VIA) +=via.o
43 43
44
diff --git a/drivers/char/drm/drm.h b/drivers/char/drm/drm.h
index e8371dd87fbc..fc6598a81acd 100644
--- a/drivers/char/drm/drm.h
+++ b/drivers/char/drm/drm.h
@@ -98,7 +98,7 @@
98#define _DRM_LOCKING_CONTEXT(lock) ((lock) & ~(_DRM_LOCK_HELD|_DRM_LOCK_CONT)) 98#define _DRM_LOCKING_CONTEXT(lock) ((lock) & ~(_DRM_LOCK_HELD|_DRM_LOCK_CONT))
99 99
100 100
101typedef unsigned long drm_handle_t; 101typedef unsigned int drm_handle_t;
102typedef unsigned int drm_context_t; 102typedef unsigned int drm_context_t;
103typedef unsigned int drm_drawable_t; 103typedef unsigned int drm_drawable_t;
104typedef unsigned int drm_magic_t; 104typedef unsigned int drm_magic_t;
@@ -209,7 +209,8 @@ typedef enum drm_map_type {
209 _DRM_REGISTERS = 1, /**< no caching, no core dump */ 209 _DRM_REGISTERS = 1, /**< no caching, no core dump */
210 _DRM_SHM = 2, /**< shared, cached */ 210 _DRM_SHM = 2, /**< shared, cached */
211 _DRM_AGP = 3, /**< AGP/GART */ 211 _DRM_AGP = 3, /**< AGP/GART */
212 _DRM_SCATTER_GATHER = 4 /**< Scatter/gather memory for PCI DMA */ 212 _DRM_SCATTER_GATHER = 4, /**< Scatter/gather memory for PCI DMA */
213 _DRM_CONSISTENT = 5, /**< Consistent memory for PCI DMA */
213} drm_map_type_t; 214} drm_map_type_t;
214 215
215 216
@@ -368,7 +369,8 @@ typedef struct drm_buf_desc {
368 enum { 369 enum {
369 _DRM_PAGE_ALIGN = 0x01, /**< Align on page boundaries for DMA */ 370 _DRM_PAGE_ALIGN = 0x01, /**< Align on page boundaries for DMA */
370 _DRM_AGP_BUFFER = 0x02, /**< Buffer is in AGP space */ 371 _DRM_AGP_BUFFER = 0x02, /**< Buffer is in AGP space */
371 _DRM_SG_BUFFER = 0x04 /**< Scatter/gather memory buffer */ 372 _DRM_SG_BUFFER = 0x04, /**< Scatter/gather memory buffer */
373 _DRM_FB_BUFFER = 0x08 /**< Buffer is in frame buffer */
372 } flags; 374 } flags;
373 unsigned long agp_start; /**< 375 unsigned long agp_start; /**<
374 * Start address of where the AGP buffers are 376 * Start address of where the AGP buffers are
diff --git a/drivers/char/drm/drmP.h b/drivers/char/drm/drmP.h
index 5df09cc8c6db..6f98701dfe15 100644
--- a/drivers/char/drm/drmP.h
+++ b/drivers/char/drm/drmP.h
@@ -53,7 +53,6 @@
53#include <linux/init.h> 53#include <linux/init.h>
54#include <linux/file.h> 54#include <linux/file.h>
55#include <linux/pci.h> 55#include <linux/pci.h>
56#include <linux/version.h>
57#include <linux/jiffies.h> 56#include <linux/jiffies.h>
58#include <linux/smp_lock.h> /* For (un)lock_kernel */ 57#include <linux/smp_lock.h> /* For (un)lock_kernel */
59#include <linux/mm.h> 58#include <linux/mm.h>
@@ -96,6 +95,7 @@
96#define DRIVER_IRQ_SHARED 0x80 95#define DRIVER_IRQ_SHARED 0x80
97#define DRIVER_IRQ_VBL 0x100 96#define DRIVER_IRQ_VBL 0x100
98#define DRIVER_DMA_QUEUE 0x200 97#define DRIVER_DMA_QUEUE 0x200
98#define DRIVER_FB_DMA 0x400
99 99
100/***********************************************************************/ 100/***********************************************************************/
101/** \name Begin the DRM... */ 101/** \name Begin the DRM... */
@@ -160,36 +160,7 @@
160#define pte_unmap(pte) 160#define pte_unmap(pte)
161#endif 161#endif
162 162
163#if LINUX_VERSION_CODE < KERNEL_VERSION(2,4,19)
164static inline struct page * vmalloc_to_page(void * vmalloc_addr)
165{
166 unsigned long addr = (unsigned long) vmalloc_addr;
167 struct page *page = NULL;
168 pgd_t *pgd = pgd_offset_k(addr);
169 pmd_t *pmd;
170 pte_t *ptep, pte;
171
172 if (!pgd_none(*pgd)) {
173 pmd = pmd_offset(pgd, addr);
174 if (!pmd_none(*pmd)) {
175 preempt_disable();
176 ptep = pte_offset_map(pmd, addr);
177 pte = *ptep;
178 if (pte_present(pte))
179 page = pte_page(pte);
180 pte_unmap(ptep);
181 preempt_enable();
182 }
183 }
184 return page;
185}
186#endif
187
188#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0)
189#define DRM_RPR_ARG(vma)
190#else
191#define DRM_RPR_ARG(vma) vma, 163#define DRM_RPR_ARG(vma) vma,
192#endif
193 164
194#define VM_OFFSET(vma) ((vma)->vm_pgoff << PAGE_SHIFT) 165#define VM_OFFSET(vma) ((vma)->vm_pgoff << PAGE_SHIFT)
195 166
@@ -474,7 +445,8 @@ typedef struct drm_device_dma {
474 unsigned long byte_count; 445 unsigned long byte_count;
475 enum { 446 enum {
476 _DRM_DMA_USE_AGP = 0x01, 447 _DRM_DMA_USE_AGP = 0x01,
477 _DRM_DMA_USE_SG = 0x02 448 _DRM_DMA_USE_SG = 0x02,
449 _DRM_DMA_USE_FB = 0x04
478 } flags; 450 } flags;
479 451
480} drm_device_dma_t; 452} drm_device_dma_t;
@@ -525,12 +497,19 @@ typedef struct drm_sigdata {
525 drm_hw_lock_t *lock; 497 drm_hw_lock_t *lock;
526} drm_sigdata_t; 498} drm_sigdata_t;
527 499
500typedef struct drm_dma_handle {
501 dma_addr_t busaddr;
502 void *vaddr;
503 size_t size;
504} drm_dma_handle_t;
505
528/** 506/**
529 * Mappings list 507 * Mappings list
530 */ 508 */
531typedef struct drm_map_list { 509typedef struct drm_map_list {
532 struct list_head head; /**< list head */ 510 struct list_head head; /**< list head */
533 drm_map_t *map; /**< mapping */ 511 drm_map_t *map; /**< mapping */
512 unsigned int user_token;
534} drm_map_list_t; 513} drm_map_list_t;
535 514
536typedef drm_map_t drm_local_map_t; 515typedef drm_map_t drm_local_map_t;
@@ -578,7 +557,22 @@ struct drm_driver {
578 int (*kernel_context_switch)(struct drm_device *dev, int old, int new); 557 int (*kernel_context_switch)(struct drm_device *dev, int old, int new);
579 void (*kernel_context_switch_unlock)(struct drm_device *dev, drm_lock_t *lock); 558 void (*kernel_context_switch_unlock)(struct drm_device *dev, drm_lock_t *lock);
580 int (*vblank_wait)(struct drm_device *dev, unsigned int *sequence); 559 int (*vblank_wait)(struct drm_device *dev, unsigned int *sequence);
560
561 /**
562 * Called by \c drm_device_is_agp. Typically used to determine if a
563 * card is really attached to AGP or not.
564 *
565 * \param dev DRM device handle
566 *
567 * \returns
568 * One of three values is returned depending on whether or not the
569 * card is absolutely \b not AGP (return of 0), absolutely \b is AGP
570 * (return of 1), or may or may not be AGP (return of 2).
571 */
572 int (*device_is_agp) (struct drm_device * dev);
573
581 /* these have to be filled in */ 574 /* these have to be filled in */
575
582 int (*postinit)(struct drm_device *, unsigned long flags); 576 int (*postinit)(struct drm_device *, unsigned long flags);
583 irqreturn_t (*irq_handler)( DRM_IRQ_ARGS ); 577 irqreturn_t (*irq_handler)( DRM_IRQ_ARGS );
584 void (*irq_preinstall)(struct drm_device *dev); 578 void (*irq_preinstall)(struct drm_device *dev);
@@ -722,12 +716,8 @@ typedef struct drm_device {
722 int pci_slot; /**< PCI slot number */ 716 int pci_slot; /**< PCI slot number */
723 int pci_func; /**< PCI function number */ 717 int pci_func; /**< PCI function number */
724#ifdef __alpha__ 718#ifdef __alpha__
725#if LINUX_VERSION_CODE < KERNEL_VERSION(2,4,3)
726 struct pci_controler *hose;
727#else
728 struct pci_controller *hose; 719 struct pci_controller *hose;
729#endif 720#endif
730#endif
731 drm_sg_mem_t *sg; /**< Scatter gather memory */ 721 drm_sg_mem_t *sg; /**< Scatter gather memory */
732 unsigned long *ctx_bitmap; /**< context bitmap */ 722 unsigned long *ctx_bitmap; /**< context bitmap */
733 void *dev_private; /**< device private data */ 723 void *dev_private; /**< device private data */
@@ -736,6 +726,7 @@ typedef struct drm_device {
736 726
737 struct drm_driver *driver; 727 struct drm_driver *driver;
738 drm_local_map_t *agp_buffer_map; 728 drm_local_map_t *agp_buffer_map;
729 unsigned int agp_buffer_token;
739 drm_head_t primary; /**< primary screen head */ 730 drm_head_t primary; /**< primary screen head */
740} drm_device_t; 731} drm_device_t;
741 732
@@ -806,7 +797,7 @@ extern void *drm_ioremap_nocache(unsigned long offset, unsigned long size,
806 drm_device_t *dev); 797 drm_device_t *dev);
807extern void drm_ioremapfree(void *pt, unsigned long size, drm_device_t *dev); 798extern void drm_ioremapfree(void *pt, unsigned long size, drm_device_t *dev);
808 799
809extern DRM_AGP_MEM *drm_alloc_agp(struct agp_bridge_data *bridge, int pages, u32 type); 800extern DRM_AGP_MEM *drm_alloc_agp(drm_device_t *dev, int pages, u32 type);
810extern int drm_free_agp(DRM_AGP_MEM *handle, int pages); 801extern int drm_free_agp(DRM_AGP_MEM *handle, int pages);
811extern int drm_bind_agp(DRM_AGP_MEM *handle, unsigned int start); 802extern int drm_bind_agp(DRM_AGP_MEM *handle, unsigned int start);
812extern int drm_unbind_agp(DRM_AGP_MEM *handle); 803extern int drm_unbind_agp(DRM_AGP_MEM *handle);
@@ -881,11 +872,19 @@ extern int drm_lock_free(drm_device_t *dev,
881 unsigned int context); 872 unsigned int context);
882 873
883 /* Buffer management support (drm_bufs.h) */ 874 /* Buffer management support (drm_bufs.h) */
875extern int drm_addbufs_agp(drm_device_t *dev, drm_buf_desc_t *request);
876extern int drm_addbufs_pci(drm_device_t *dev, drm_buf_desc_t *request);
877extern int drm_addmap(drm_device_t *dev, unsigned int offset,
878 unsigned int size, drm_map_type_t type,
879 drm_map_flags_t flags, drm_local_map_t **map_ptr);
880extern int drm_addmap_ioctl(struct inode *inode, struct file *filp,
881 unsigned int cmd, unsigned long arg);
882extern int drm_rmmap(drm_device_t *dev, drm_local_map_t *map);
883extern int drm_rmmap_locked(drm_device_t *dev, drm_local_map_t *map);
884extern int drm_rmmap_ioctl(struct inode *inode, struct file *filp,
885 unsigned int cmd, unsigned long arg);
886
884extern int drm_order( unsigned long size ); 887extern int drm_order( unsigned long size );
885extern int drm_addmap( struct inode *inode, struct file *filp,
886 unsigned int cmd, unsigned long arg );
887extern int drm_rmmap( struct inode *inode, struct file *filp,
888 unsigned int cmd, unsigned long arg );
889extern int drm_addbufs( struct inode *inode, struct file *filp, 888extern int drm_addbufs( struct inode *inode, struct file *filp,
890 unsigned int cmd, unsigned long arg ); 889 unsigned int cmd, unsigned long arg );
891extern int drm_infobufs( struct inode *inode, struct file *filp, 890extern int drm_infobufs( struct inode *inode, struct file *filp,
@@ -896,6 +895,10 @@ extern int drm_freebufs( struct inode *inode, struct file *filp,
896 unsigned int cmd, unsigned long arg ); 895 unsigned int cmd, unsigned long arg );
897extern int drm_mapbufs( struct inode *inode, struct file *filp, 896extern int drm_mapbufs( struct inode *inode, struct file *filp,
898 unsigned int cmd, unsigned long arg ); 897 unsigned int cmd, unsigned long arg );
898extern unsigned long drm_get_resource_start(drm_device_t *dev,
899 unsigned int resource);
900extern unsigned long drm_get_resource_len(drm_device_t *dev,
901 unsigned int resource);
899 902
900 /* DMA support (drm_dma.h) */ 903 /* DMA support (drm_dma.h) */
901extern int drm_dma_setup(drm_device_t *dev); 904extern int drm_dma_setup(drm_device_t *dev);
@@ -919,15 +922,18 @@ extern void drm_vbl_send_signals( drm_device_t *dev );
919 922
920 /* AGP/GART support (drm_agpsupport.h) */ 923 /* AGP/GART support (drm_agpsupport.h) */
921extern drm_agp_head_t *drm_agp_init(drm_device_t *dev); 924extern drm_agp_head_t *drm_agp_init(drm_device_t *dev);
922extern int drm_agp_acquire(struct inode *inode, struct file *filp, 925extern int drm_agp_acquire(drm_device_t * dev);
923 unsigned int cmd, unsigned long arg); 926extern int drm_agp_acquire_ioctl(struct inode *inode, struct file *filp,
924extern void drm_agp_do_release(drm_device_t *dev); 927 unsigned int cmd, unsigned long arg);
925extern int drm_agp_release(struct inode *inode, struct file *filp, 928extern int drm_agp_release(drm_device_t *dev);
926 unsigned int cmd, unsigned long arg); 929extern int drm_agp_release_ioctl(struct inode *inode, struct file *filp,
927extern int drm_agp_enable(struct inode *inode, struct file *filp, 930 unsigned int cmd, unsigned long arg);
928 unsigned int cmd, unsigned long arg); 931extern int drm_agp_enable(drm_device_t *dev, drm_agp_mode_t mode);
929extern int drm_agp_info(struct inode *inode, struct file *filp, 932extern int drm_agp_enable_ioctl(struct inode *inode, struct file *filp,
930 unsigned int cmd, unsigned long arg); 933 unsigned int cmd, unsigned long arg);
934extern int drm_agp_info(drm_device_t * dev, drm_agp_info_t *info);
935extern int drm_agp_info_ioctl(struct inode *inode, struct file *filp,
936 unsigned int cmd, unsigned long arg);
931extern int drm_agp_alloc(struct inode *inode, struct file *filp, 937extern int drm_agp_alloc(struct inode *inode, struct file *filp,
932 unsigned int cmd, unsigned long arg); 938 unsigned int cmd, unsigned long arg);
933extern int drm_agp_free(struct inode *inode, struct file *filp, 939extern int drm_agp_free(struct inode *inode, struct file *filp,
@@ -976,12 +982,10 @@ extern int drm_ati_pcigart_cleanup(drm_device_t *dev,
976 unsigned long addr, 982 unsigned long addr,
977 dma_addr_t bus_addr); 983 dma_addr_t bus_addr);
978 984
979extern void *drm_pci_alloc(drm_device_t * dev, size_t size, 985extern drm_dma_handle_t *drm_pci_alloc(drm_device_t *dev, size_t size,
980 size_t align, dma_addr_t maxaddr, 986 size_t align, dma_addr_t maxaddr);
981 dma_addr_t * busaddr); 987extern void __drm_pci_free(drm_device_t *dev, drm_dma_handle_t *dmah);
982 988extern void drm_pci_free(drm_device_t *dev, drm_dma_handle_t *dmah);
983extern void drm_pci_free(drm_device_t * dev, size_t size,
984 void *vaddr, dma_addr_t busaddr);
985 989
986 /* sysfs support (drm_sysfs.c) */ 990 /* sysfs support (drm_sysfs.c) */
987struct drm_sysfs_class; 991struct drm_sysfs_class;
@@ -1012,17 +1016,26 @@ static __inline__ void drm_core_ioremapfree(struct drm_map *map, struct drm_devi
1012 drm_ioremapfree( map->handle, map->size, dev ); 1016 drm_ioremapfree( map->handle, map->size, dev );
1013} 1017}
1014 1018
1015static __inline__ struct drm_map *drm_core_findmap(struct drm_device *dev, unsigned long offset) 1019static __inline__ struct drm_map *drm_core_findmap(struct drm_device *dev, unsigned int token)
1016{ 1020{
1017 struct list_head *_list; 1021 drm_map_list_t *_entry;
1018 list_for_each( _list, &dev->maplist->head ) { 1022 list_for_each_entry(_entry, &dev->maplist->head, head)
1019 drm_map_list_t *_entry = list_entry( _list, drm_map_list_t, head ); 1023 if (_entry->user_token == token)
1020 if ( _entry->map &&
1021 _entry->map->offset == offset ) {
1022 return _entry->map; 1024 return _entry->map;
1025 return NULL;
1026}
1027
1028static __inline__ int drm_device_is_agp(drm_device_t *dev)
1029{
1030 if ( dev->driver->device_is_agp != NULL ) {
1031 int err = (*dev->driver->device_is_agp)( dev );
1032
1033 if (err != 2) {
1034 return err;
1023 } 1035 }
1024 } 1036 }
1025 return NULL; 1037
1038 return pci_find_capability(dev->pdev, PCI_CAP_ID_AGP);
1026} 1039}
1027 1040
1028static __inline__ void drm_core_dropmap(struct drm_map *map) 1041static __inline__ void drm_core_dropmap(struct drm_map *map)
diff --git a/drivers/char/drm/drm_agpsupport.c b/drivers/char/drm/drm_agpsupport.c
index 8d94c0b5fa44..8c215adcb4b2 100644
--- a/drivers/char/drm/drm_agpsupport.c
+++ b/drivers/char/drm/drm_agpsupport.c
@@ -37,7 +37,7 @@
37#if __OS_HAS_AGP 37#if __OS_HAS_AGP
38 38
39/** 39/**
40 * AGP information ioctl. 40 * Get AGP information.
41 * 41 *
42 * \param inode device inode. 42 * \param inode device inode.
43 * \param filp file pointer. 43 * \param filp file pointer.
@@ -48,51 +48,56 @@
48 * Verifies the AGP device has been initialized and acquired and fills in the 48 * Verifies the AGP device has been initialized and acquired and fills in the
49 * drm_agp_info structure with the information in drm_agp_head::agp_info. 49 * drm_agp_info structure with the information in drm_agp_head::agp_info.
50 */ 50 */
51int drm_agp_info(struct inode *inode, struct file *filp, 51int drm_agp_info(drm_device_t *dev, drm_agp_info_t *info)
52 unsigned int cmd, unsigned long arg)
53{ 52{
54 drm_file_t *priv = filp->private_data;
55 drm_device_t *dev = priv->head->dev;
56 DRM_AGP_KERN *kern; 53 DRM_AGP_KERN *kern;
57 drm_agp_info_t info;
58 54
59 if (!dev->agp || !dev->agp->acquired) 55 if (!dev->agp || !dev->agp->acquired)
60 return -EINVAL; 56 return -EINVAL;
61 57
62 kern = &dev->agp->agp_info; 58 kern = &dev->agp->agp_info;
63 info.agp_version_major = kern->version.major; 59 info->agp_version_major = kern->version.major;
64 info.agp_version_minor = kern->version.minor; 60 info->agp_version_minor = kern->version.minor;
65 info.mode = kern->mode; 61 info->mode = kern->mode;
66 info.aperture_base = kern->aper_base; 62 info->aperture_base = kern->aper_base;
67 info.aperture_size = kern->aper_size * 1024 * 1024; 63 info->aperture_size = kern->aper_size * 1024 * 1024;
68 info.memory_allowed = kern->max_memory << PAGE_SHIFT; 64 info->memory_allowed = kern->max_memory << PAGE_SHIFT;
69 info.memory_used = kern->current_memory << PAGE_SHIFT; 65 info->memory_used = kern->current_memory << PAGE_SHIFT;
70 info.id_vendor = kern->device->vendor; 66 info->id_vendor = kern->device->vendor;
71 info.id_device = kern->device->device; 67 info->id_device = kern->device->device;
72 68
73 if (copy_to_user((drm_agp_info_t __user *)arg, &info, sizeof(info))) 69 return 0;
70}
71EXPORT_SYMBOL(drm_agp_info);
72
73int drm_agp_info_ioctl(struct inode *inode, struct file *filp,
74 unsigned int cmd, unsigned long arg)
75{
76 drm_file_t *priv = filp->private_data;
77 drm_device_t *dev = priv->head->dev;
78 drm_agp_info_t info;
79 int err;
80
81 err = drm_agp_info(dev, &info);
82 if (err)
83 return err;
84
85 if (copy_to_user((drm_agp_info_t __user *) arg, &info, sizeof(info)))
74 return -EFAULT; 86 return -EFAULT;
75 return 0; 87 return 0;
76} 88}
77 89
78/** 90/**
79 * Acquire the AGP device (ioctl). 91 * Acquire the AGP device.
80 * 92 *
81 * \param inode device inode. 93 * \param dev DRM device that is to acquire AGP
82 * \param filp file pointer.
83 * \param cmd command.
84 * \param arg user argument.
85 * \return zero on success or a negative number on failure. 94 * \return zero on success or a negative number on failure.
86 * 95 *
87 * Verifies the AGP device hasn't been acquired before and calls 96 * Verifies the AGP device hasn't been acquired before and calls
88 * agp_acquire(). 97 * \c agp_backend_acquire.
89 */ 98 */
90int drm_agp_acquire(struct inode *inode, struct file *filp, 99int drm_agp_acquire(drm_device_t *dev)
91 unsigned int cmd, unsigned long arg)
92{ 100{
93 drm_file_t *priv = filp->private_data;
94 drm_device_t *dev = priv->head->dev;
95
96 if (!dev->agp) 101 if (!dev->agp)
97 return -ENODEV; 102 return -ENODEV;
98 if (dev->agp->acquired) 103 if (dev->agp->acquired)
@@ -102,9 +107,10 @@ int drm_agp_acquire(struct inode *inode, struct file *filp,
102 dev->agp->acquired = 1; 107 dev->agp->acquired = 1;
103 return 0; 108 return 0;
104} 109}
110EXPORT_SYMBOL(drm_agp_acquire);
105 111
106/** 112/**
107 * Release the AGP device (ioctl). 113 * Acquire the AGP device (ioctl).
108 * 114 *
109 * \param inode device inode. 115 * \param inode device inode.
110 * \param filp file pointer. 116 * \param filp file pointer.
@@ -112,63 +118,80 @@ int drm_agp_acquire(struct inode *inode, struct file *filp,
112 * \param arg user argument. 118 * \param arg user argument.
113 * \return zero on success or a negative number on failure. 119 * \return zero on success or a negative number on failure.
114 * 120 *
115 * Verifies the AGP device has been acquired and calls agp_backend_release(). 121 * Verifies the AGP device hasn't been acquired before and calls
122 * \c agp_backend_acquire.
116 */ 123 */
117int drm_agp_release(struct inode *inode, struct file *filp, 124int drm_agp_acquire_ioctl(struct inode *inode, struct file *filp,
118 unsigned int cmd, unsigned long arg) 125 unsigned int cmd, unsigned long arg)
119{ 126{
120 drm_file_t *priv = filp->private_data; 127 drm_file_t *priv = filp->private_data;
121 drm_device_t *dev = priv->head->dev; 128
129 return drm_agp_acquire( (drm_device_t *) priv->head->dev );
130}
122 131
132/**
133 * Release the AGP device.
134 *
135 * \param dev DRM device that is to release AGP
136 * \return zero on success or a negative number on failure.
137 *
138 * Verifies the AGP device has been acquired and calls \c agp_backend_release.
139 */
140int drm_agp_release(drm_device_t *dev)
141{
123 if (!dev->agp || !dev->agp->acquired) 142 if (!dev->agp || !dev->agp->acquired)
124 return -EINVAL; 143 return -EINVAL;
125 agp_backend_release(dev->agp->bridge); 144 agp_backend_release(dev->agp->bridge);
126 dev->agp->acquired = 0; 145 dev->agp->acquired = 0;
127 return 0; 146 return 0;
128
129} 147}
148EXPORT_SYMBOL(drm_agp_release);
130 149
131/** 150int drm_agp_release_ioctl(struct inode *inode, struct file *filp,
132 * Release the AGP device. 151 unsigned int cmd, unsigned long arg)
133 *
134 * Calls agp_backend_release().
135 */
136void drm_agp_do_release(drm_device_t *dev)
137{ 152{
138 agp_backend_release(dev->agp->bridge); 153 drm_file_t *priv = filp->private_data;
154 drm_device_t *dev = priv->head->dev;
155
156 return drm_agp_release(dev);
139} 157}
140 158
141/** 159/**
142 * Enable the AGP bus. 160 * Enable the AGP bus.
143 * 161 *
144 * \param inode device inode. 162 * \param dev DRM device that has previously acquired AGP.
145 * \param filp file pointer. 163 * \param mode Requested AGP mode.
146 * \param cmd command.
147 * \param arg pointer to a drm_agp_mode structure.
148 * \return zero on success or a negative number on failure. 164 * \return zero on success or a negative number on failure.
149 * 165 *
150 * Verifies the AGP device has been acquired but not enabled, and calls 166 * Verifies the AGP device has been acquired but not enabled, and calls
151 * agp_enable(). 167 * \c agp_enable.
152 */ 168 */
153int drm_agp_enable(struct inode *inode, struct file *filp, 169int drm_agp_enable(drm_device_t *dev, drm_agp_mode_t mode)
154 unsigned int cmd, unsigned long arg)
155{ 170{
156 drm_file_t *priv = filp->private_data;
157 drm_device_t *dev = priv->head->dev;
158 drm_agp_mode_t mode;
159
160 if (!dev->agp || !dev->agp->acquired) 171 if (!dev->agp || !dev->agp->acquired)
161 return -EINVAL; 172 return -EINVAL;
162 173
163 if (copy_from_user(&mode, (drm_agp_mode_t __user *)arg, sizeof(mode)))
164 return -EFAULT;
165
166 dev->agp->mode = mode.mode; 174 dev->agp->mode = mode.mode;
167 agp_enable(dev->agp->bridge, mode.mode); 175 agp_enable(dev->agp->bridge, mode.mode);
168 dev->agp->base = dev->agp->agp_info.aper_base; 176 dev->agp->base = dev->agp->agp_info.aper_base;
169 dev->agp->enabled = 1; 177 dev->agp->enabled = 1;
170 return 0; 178 return 0;
171} 179}
180EXPORT_SYMBOL(drm_agp_enable);
181
182int drm_agp_enable_ioctl(struct inode *inode, struct file *filp,
183 unsigned int cmd, unsigned long arg)
184{
185 drm_file_t *priv = filp->private_data;
186 drm_device_t *dev = priv->head->dev;
187 drm_agp_mode_t mode;
188
189
190 if (copy_from_user(&mode, (drm_agp_mode_t __user *) arg, sizeof(mode)))
191 return -EFAULT;
192
193 return drm_agp_enable(dev, mode);
194}
172 195
173/** 196/**
174 * Allocate AGP memory. 197 * Allocate AGP memory.
@@ -206,7 +229,7 @@ int drm_agp_alloc(struct inode *inode, struct file *filp,
206 pages = (request.size + PAGE_SIZE - 1) / PAGE_SIZE; 229 pages = (request.size + PAGE_SIZE - 1) / PAGE_SIZE;
207 type = (u32) request.type; 230 type = (u32) request.type;
208 231
209 if (!(memory = drm_alloc_agp(dev->agp->bridge, pages, type))) { 232 if (!(memory = drm_alloc_agp(dev, pages, type))) {
210 drm_free(entry, sizeof(*entry), DRM_MEM_AGPLISTS); 233 drm_free(entry, sizeof(*entry), DRM_MEM_AGPLISTS);
211 return -ENOMEM; 234 return -ENOMEM;
212 } 235 }
@@ -403,13 +426,8 @@ drm_agp_head_t *drm_agp_init(drm_device_t *dev)
403 return NULL; 426 return NULL;
404 } 427 }
405 head->memory = NULL; 428 head->memory = NULL;
406#if LINUX_VERSION_CODE <= 0x020408
407 head->cant_use_aperture = 0;
408 head->page_mask = ~(0xfff);
409#else
410 head->cant_use_aperture = head->agp_info.cant_use_aperture; 429 head->cant_use_aperture = head->agp_info.cant_use_aperture;
411 head->page_mask = head->agp_info.page_mask; 430 head->page_mask = head->agp_info.page_mask;
412#endif
413 431
414 return head; 432 return head;
415} 433}
@@ -436,6 +454,7 @@ int drm_agp_bind_memory(DRM_AGP_MEM *handle, off_t start)
436 return -EINVAL; 454 return -EINVAL;
437 return agp_bind_memory(handle, start); 455 return agp_bind_memory(handle, start);
438} 456}
457EXPORT_SYMBOL(drm_agp_bind_memory);
439 458
440/** Calls agp_unbind_memory() */ 459/** Calls agp_unbind_memory() */
441int drm_agp_unbind_memory(DRM_AGP_MEM *handle) 460int drm_agp_unbind_memory(DRM_AGP_MEM *handle)
diff --git a/drivers/char/drm/drm_bufs.c b/drivers/char/drm/drm_bufs.c
index 4c6191d231b8..e0743ebbe4bd 100644
--- a/drivers/char/drm/drm_bufs.c
+++ b/drivers/char/drm/drm_bufs.c
@@ -36,37 +36,69 @@
36#include <linux/vmalloc.h> 36#include <linux/vmalloc.h>
37#include "drmP.h" 37#include "drmP.h"
38 38
39/** 39unsigned long drm_get_resource_start(drm_device_t *dev, unsigned int resource)
40 * Compute size order. Returns the exponent of the smaller power of two which
41 * is greater or equal to given number.
42 *
43 * \param size size.
44 * \return order.
45 *
46 * \todo Can be made faster.
47 */
48int drm_order( unsigned long size )
49{ 40{
50 int order; 41 return pci_resource_start(dev->pdev, resource);
51 unsigned long tmp; 42}
43EXPORT_SYMBOL(drm_get_resource_start);
52 44
53 for (order = 0, tmp = size >> 1; tmp; tmp >>= 1, order++) 45unsigned long drm_get_resource_len(drm_device_t *dev, unsigned int resource)
54 ; 46{
47 return pci_resource_len(dev->pdev, resource);
48}
49EXPORT_SYMBOL(drm_get_resource_len);
55 50
56 if (size & (size - 1)) 51static drm_local_map_t *drm_find_matching_map(drm_device_t *dev,
57 ++order; 52 drm_local_map_t *map)
53{
54 struct list_head *list;
58 55
59 return order; 56 list_for_each(list, &dev->maplist->head) {
57 drm_map_list_t *entry = list_entry(list, drm_map_list_t, head);
58 if (entry->map && map->type == entry->map->type &&
59 entry->map->offset == map->offset) {
60 return entry->map;
61 }
62 }
63
64 return NULL;
60} 65}
61EXPORT_SYMBOL(drm_order);
62 66
63#ifdef CONFIG_COMPAT
64/* 67/*
65 * Used to allocate 32-bit handles for _DRM_SHM regions 68 * Used to allocate 32-bit handles for mappings.
66 * The 0x10000000 value is chosen to be out of the way of
67 * FB/register and GART physical addresses.
68 */ 69 */
69static unsigned int map32_handle = 0x10000000; 70#define START_RANGE 0x10000000
71#define END_RANGE 0x40000000
72
73#ifdef _LP64
74static __inline__ unsigned int HandleID(unsigned long lhandle, drm_device_t *dev)
75{
76 static unsigned int map32_handle = START_RANGE;
77 unsigned int hash;
78
79 if (lhandle & 0xffffffff00000000) {
80 hash = map32_handle;
81 map32_handle += PAGE_SIZE;
82 if (map32_handle > END_RANGE)
83 map32_handle = START_RANGE;
84 } else
85 hash = lhandle;
86
87 while (1) {
88 drm_map_list_t *_entry;
89 list_for_each_entry(_entry, &dev->maplist->head,head) {
90 if (_entry->user_token == hash)
91 break;
92 }
93 if (&_entry->head == &dev->maplist->head)
94 return hash;
95
96 hash += PAGE_SIZE;
97 map32_handle += PAGE_SIZE;
98 }
99}
100#else
101# define HandleID(x,dev) (unsigned int)(x)
70#endif 102#endif
71 103
72/** 104/**
@@ -82,25 +114,23 @@ static unsigned int map32_handle = 0x10000000;
82 * type. Adds the map to the map list drm_device::maplist. Adds MTRR's where 114 * type. Adds the map to the map list drm_device::maplist. Adds MTRR's where
83 * applicable and if supported by the kernel. 115 * applicable and if supported by the kernel.
84 */ 116 */
85int drm_addmap( struct inode *inode, struct file *filp, 117int drm_addmap(drm_device_t * dev, unsigned int offset,
86 unsigned int cmd, unsigned long arg ) 118 unsigned int size, drm_map_type_t type,
119 drm_map_flags_t flags, drm_local_map_t ** map_ptr)
87{ 120{
88 drm_file_t *priv = filp->private_data;
89 drm_device_t *dev = priv->head->dev;
90 drm_map_t *map; 121 drm_map_t *map;
91 drm_map_t __user *argp = (void __user *)arg;
92 drm_map_list_t *list; 122 drm_map_list_t *list;
93 123 drm_dma_handle_t *dmah;
94 if ( !(filp->f_mode & 3) ) return -EACCES; /* Require read/write */ 124 drm_local_map_t *found_map;
95 125
96 map = drm_alloc( sizeof(*map), DRM_MEM_MAPS ); 126 map = drm_alloc( sizeof(*map), DRM_MEM_MAPS );
97 if ( !map ) 127 if ( !map )
98 return -ENOMEM; 128 return -ENOMEM;
99 129
100 if ( copy_from_user( map, argp, sizeof(*map) ) ) { 130 map->offset = offset;
101 drm_free( map, sizeof(*map), DRM_MEM_MAPS ); 131 map->size = size;
102 return -EFAULT; 132 map->flags = flags;
103 } 133 map->type = type;
104 134
105 /* Only allow shared memory to be removable since we only keep enough 135 /* Only allow shared memory to be removable since we only keep enough
106 * book keeping information about shared memory to allow for removal 136 * book keeping information about shared memory to allow for removal
@@ -122,7 +152,7 @@ int drm_addmap( struct inode *inode, struct file *filp,
122 switch ( map->type ) { 152 switch ( map->type ) {
123 case _DRM_REGISTERS: 153 case _DRM_REGISTERS:
124 case _DRM_FRAME_BUFFER: 154 case _DRM_FRAME_BUFFER:
125#if !defined(__sparc__) && !defined(__alpha__) && !defined(__ia64__) 155#if !defined(__sparc__) && !defined(__alpha__) && !defined(__ia64__) && !defined(__powerpc64__) && !defined(__x86_64__)
126 if ( map->offset + map->size < map->offset || 156 if ( map->offset + map->size < map->offset ||
127 map->offset < virt_to_phys(high_memory) ) { 157 map->offset < virt_to_phys(high_memory) ) {
128 drm_free( map, sizeof(*map), DRM_MEM_MAPS ); 158 drm_free( map, sizeof(*map), DRM_MEM_MAPS );
@@ -132,6 +162,24 @@ int drm_addmap( struct inode *inode, struct file *filp,
132#ifdef __alpha__ 162#ifdef __alpha__
133 map->offset += dev->hose->mem_space->start; 163 map->offset += dev->hose->mem_space->start;
134#endif 164#endif
165 /* Some drivers preinitialize some maps, without the X Server
166 * needing to be aware of it. Therefore, we just return success
167 * when the server tries to create a duplicate map.
168 */
169 found_map = drm_find_matching_map(dev, map);
170 if (found_map != NULL) {
171 if (found_map->size != map->size) {
172 DRM_DEBUG("Matching maps of type %d with "
173 "mismatched sizes, (%ld vs %ld)\n",
174 map->type, map->size, found_map->size);
175 found_map->size = map->size;
176 }
177
178 drm_free(map, sizeof(*map), DRM_MEM_MAPS);
179 *map_ptr = found_map;
180 return 0;
181 }
182
135 if (drm_core_has_MTRR(dev)) { 183 if (drm_core_has_MTRR(dev)) {
136 if ( map->type == _DRM_FRAME_BUFFER || 184 if ( map->type == _DRM_FRAME_BUFFER ||
137 (map->flags & _DRM_WRITE_COMBINING) ) { 185 (map->flags & _DRM_WRITE_COMBINING) ) {
@@ -178,9 +226,22 @@ int drm_addmap( struct inode *inode, struct file *filp,
178 drm_free(map, sizeof(*map), DRM_MEM_MAPS); 226 drm_free(map, sizeof(*map), DRM_MEM_MAPS);
179 return -EINVAL; 227 return -EINVAL;
180 } 228 }
181 map->offset += dev->sg->handle; 229 map->offset += (unsigned long)dev->sg->virtual;
230 break;
231 case _DRM_CONSISTENT:
232 /* dma_addr_t is 64bit on i386 with CONFIG_HIGHMEM64G,
233 * As we're limiting the address to 2^32-1 (or less),
234 * casting it down to 32 bits is no problem, but we
235 * need to point to a 64bit variable first. */
236 dmah = drm_pci_alloc(dev, map->size, map->size, 0xffffffffUL);
237 if (!dmah) {
238 drm_free(map, sizeof(*map), DRM_MEM_MAPS);
239 return -ENOMEM;
240 }
241 map->handle = dmah->vaddr;
242 map->offset = (unsigned long)dmah->busaddr;
243 kfree(dmah);
182 break; 244 break;
183
184 default: 245 default:
185 drm_free( map, sizeof(*map), DRM_MEM_MAPS ); 246 drm_free( map, sizeof(*map), DRM_MEM_MAPS );
186 return -EINVAL; 247 return -EINVAL;
@@ -196,17 +257,56 @@ int drm_addmap( struct inode *inode, struct file *filp,
196 257
197 down(&dev->struct_sem); 258 down(&dev->struct_sem);
198 list_add(&list->head, &dev->maplist->head); 259 list_add(&list->head, &dev->maplist->head);
199#ifdef CONFIG_COMPAT 260 /* Assign a 32-bit handle */
200 /* Assign a 32-bit handle for _DRM_SHM mappings */
201 /* We do it here so that dev->struct_sem protects the increment */ 261 /* We do it here so that dev->struct_sem protects the increment */
202 if (map->type == _DRM_SHM) 262 list->user_token = HandleID(map->type==_DRM_SHM
203 map->offset = map32_handle += PAGE_SIZE; 263 ? (unsigned long)map->handle
204#endif 264 : map->offset, dev);
205 up(&dev->struct_sem); 265 up(&dev->struct_sem);
206 266
207 if ( copy_to_user( argp, map, sizeof(*map) ) ) 267 *map_ptr = map;
268 return 0;
269}
270EXPORT_SYMBOL(drm_addmap);
271
272int drm_addmap_ioctl(struct inode *inode, struct file *filp,
273 unsigned int cmd, unsigned long arg)
274{
275 drm_file_t *priv = filp->private_data;
276 drm_device_t *dev = priv->head->dev;
277 drm_map_t map;
278 drm_map_t *map_ptr;
279 drm_map_t __user *argp = (void __user *)arg;
280 int err;
281 unsigned long handle = 0;
282
283 if (!(filp->f_mode & 3))
284 return -EACCES; /* Require read/write */
285
286 if (copy_from_user(& map, argp, sizeof(map))) {
287 return -EFAULT;
288 }
289
290 err = drm_addmap(dev, map.offset, map.size, map.type, map.flags,
291 &map_ptr);
292
293 if (err) {
294 return err;
295 }
296
297 {
298 drm_map_list_t *_entry;
299 list_for_each_entry(_entry, &dev->maplist->head, head) {
300 if (_entry->map == map_ptr)
301 handle = _entry->user_token;
302 }
303 if (!handle)
304 return -EFAULT;
305 }
306
307 if (copy_to_user(argp, map_ptr, sizeof(*map_ptr)))
208 return -EFAULT; 308 return -EFAULT;
209 if (copy_to_user(&argp->handle, &map->offset, sizeof(map->offset))) 309 if (put_user(handle, &argp->handle))
210 return -EFAULT; 310 return -EFAULT;
211 return 0; 311 return 0;
212} 312}
@@ -226,81 +326,138 @@ int drm_addmap( struct inode *inode, struct file *filp,
226 * its being used, and free any associate resource (such as MTRR's) if it's not 326 * its being used, and free any associate resource (such as MTRR's) if it's not
227 * being on use. 327 * being on use.
228 * 328 *
229 * \sa addmap(). 329 * \sa drm_addmap
230 */ 330 */
231int drm_rmmap(struct inode *inode, struct file *filp, 331int drm_rmmap_locked(drm_device_t *dev, drm_local_map_t *map)
232 unsigned int cmd, unsigned long arg)
233{ 332{
234 drm_file_t *priv = filp->private_data;
235 drm_device_t *dev = priv->head->dev;
236 struct list_head *list; 333 struct list_head *list;
237 drm_map_list_t *r_list = NULL; 334 drm_map_list_t *r_list = NULL;
238 drm_vma_entry_t *pt, *prev; 335 drm_dma_handle_t dmah;
239 drm_map_t *map; 336
337 /* Find the list entry for the map and remove it */
338 list_for_each(list, &dev->maplist->head) {
339 r_list = list_entry(list, drm_map_list_t, head);
340
341 if (r_list->map == map) {
342 list_del(list);
343 drm_free(list, sizeof(*list), DRM_MEM_MAPS);
344 break;
345 }
346 }
347
348 /* List has wrapped around to the head pointer, or it's empty and we
349 * didn't find anything.
350 */
351 if (list == (&dev->maplist->head)) {
352 return -EINVAL;
353 }
354
355 switch (map->type) {
356 case _DRM_REGISTERS:
357 drm_ioremapfree(map->handle, map->size, dev);
358 /* FALLTHROUGH */
359 case _DRM_FRAME_BUFFER:
360 if (drm_core_has_MTRR(dev) && map->mtrr >= 0) {
361 int retcode;
362 retcode = mtrr_del(map->mtrr, map->offset,
363 map->size);
364 DRM_DEBUG ("mtrr_del=%d\n", retcode);
365 }
366 break;
367 case _DRM_SHM:
368 vfree(map->handle);
369 break;
370 case _DRM_AGP:
371 case _DRM_SCATTER_GATHER:
372 break;
373 case _DRM_CONSISTENT:
374 dmah.vaddr = map->handle;
375 dmah.busaddr = map->offset;
376 dmah.size = map->size;
377 __drm_pci_free(dev, &dmah);
378 break;
379 }
380 drm_free(map, sizeof(*map), DRM_MEM_MAPS);
381
382 return 0;
383}
384EXPORT_SYMBOL(drm_rmmap_locked);
385
386int drm_rmmap(drm_device_t *dev, drm_local_map_t *map)
387{
388 int ret;
389
390 down(&dev->struct_sem);
391 ret = drm_rmmap_locked(dev, map);
392 up(&dev->struct_sem);
393
394 return ret;
395}
396EXPORT_SYMBOL(drm_rmmap);
397
398/* The rmmap ioctl appears to be unnecessary. All mappings are torn down on
399 * the last close of the device, and this is necessary for cleanup when things
400 * exit uncleanly. Therefore, having userland manually remove mappings seems
401 * like a pointless exercise since they're going away anyway.
402 *
403 * One use case might be after addmap is allowed for normal users for SHM and
404 * gets used by drivers that the server doesn't need to care about. This seems
405 * unlikely.
406 */
407int drm_rmmap_ioctl(struct inode *inode, struct file *filp,
408 unsigned int cmd, unsigned long arg)
409{
410 drm_file_t *priv = filp->private_data;
411 drm_device_t *dev = priv->head->dev;
240 drm_map_t request; 412 drm_map_t request;
241 int found_maps = 0; 413 drm_local_map_t *map = NULL;
414 struct list_head *list;
415 int ret;
242 416
243 if (copy_from_user(&request, (drm_map_t __user *)arg, 417 if (copy_from_user(&request, (drm_map_t __user *)arg, sizeof(request))) {
244 sizeof(request))) {
245 return -EFAULT; 418 return -EFAULT;
246 } 419 }
247 420
248 down(&dev->struct_sem); 421 down(&dev->struct_sem);
249 list = &dev->maplist->head;
250 list_for_each(list, &dev->maplist->head) { 422 list_for_each(list, &dev->maplist->head) {
251 r_list = list_entry(list, drm_map_list_t, head); 423 drm_map_list_t *r_list = list_entry(list, drm_map_list_t, head);
252 424
253 if(r_list->map && 425 if (r_list->map &&
254 r_list->map->offset == (unsigned long) request.handle && 426 r_list->user_token == (unsigned long) request.handle &&
255 r_list->map->flags & _DRM_REMOVABLE) break; 427 r_list->map->flags & _DRM_REMOVABLE) {
428 map = r_list->map;
429 break;
430 }
256 } 431 }
257 432
258 /* List has wrapped around to the head pointer, or its empty we didn't 433 /* List has wrapped around to the head pointer, or its empty we didn't
259 * find anything. 434 * find anything.
260 */ 435 */
261 if(list == (&dev->maplist->head)) { 436 if (list == (&dev->maplist->head)) {
262 up(&dev->struct_sem); 437 up(&dev->struct_sem);
263 return -EINVAL; 438 return -EINVAL;
264 } 439 }
265 map = r_list->map;
266 list_del(list);
267 drm_free(list, sizeof(*list), DRM_MEM_MAPS);
268 440
269 for (pt = dev->vmalist, prev = NULL; pt; prev = pt, pt = pt->next) { 441 if (!map)
270 if (pt->vma->vm_private_data == map) found_maps++; 442 return -EINVAL;
271 }
272 443
273 if(!found_maps) { 444 /* Register and framebuffer maps are permanent */
274 switch (map->type) { 445 if ((map->type == _DRM_REGISTERS) || (map->type == _DRM_FRAME_BUFFER)) {
275 case _DRM_REGISTERS: 446 up(&dev->struct_sem);
276 case _DRM_FRAME_BUFFER: 447 return 0;
277 if (drm_core_has_MTRR(dev)) {
278 if (map->mtrr >= 0) {
279 int retcode;
280 retcode = mtrr_del(map->mtrr,
281 map->offset,
282 map->size);
283 DRM_DEBUG("mtrr_del = %d\n", retcode);
284 }
285 }
286 drm_ioremapfree(map->handle, map->size, dev);
287 break;
288 case _DRM_SHM:
289 vfree(map->handle);
290 break;
291 case _DRM_AGP:
292 case _DRM_SCATTER_GATHER:
293 break;
294 }
295 drm_free(map, sizeof(*map), DRM_MEM_MAPS);
296 } 448 }
449
450 ret = drm_rmmap_locked(dev, map);
451
297 up(&dev->struct_sem); 452 up(&dev->struct_sem);
298 return 0; 453
454 return ret;
299} 455}
300 456
301/** 457/**
302 * Cleanup after an error on one of the addbufs() functions. 458 * Cleanup after an error on one of the addbufs() functions.
303 * 459 *
460 * \param dev DRM device.
304 * \param entry buffer entry where the error occurred. 461 * \param entry buffer entry where the error occurred.
305 * 462 *
306 * Frees any pages and buffers associated with the given entry. 463 * Frees any pages and buffers associated with the given entry.
@@ -344,25 +501,19 @@ static void drm_cleanup_buf_error(drm_device_t *dev, drm_buf_entry_t *entry)
344 501
345#if __OS_HAS_AGP 502#if __OS_HAS_AGP
346/** 503/**
347 * Add AGP buffers for DMA transfers (ioctl). 504 * Add AGP buffers for DMA transfers.
348 * 505 *
349 * \param inode device inode. 506 * \param dev drm_device_t to which the buffers are to be added.
350 * \param filp file pointer. 507 * \param request pointer to a drm_buf_desc_t describing the request.
351 * \param cmd command.
352 * \param arg pointer to a drm_buf_desc_t request.
353 * \return zero on success or a negative number on failure. 508 * \return zero on success or a negative number on failure.
354 * 509 *
355 * After some sanity checks creates a drm_buf structure for each buffer and 510 * After some sanity checks creates a drm_buf structure for each buffer and
356 * reallocates the buffer list of the same size order to accommodate the new 511 * reallocates the buffer list of the same size order to accommodate the new
357 * buffers. 512 * buffers.
358 */ 513 */
359static int drm_addbufs_agp( struct inode *inode, struct file *filp, 514int drm_addbufs_agp(drm_device_t *dev, drm_buf_desc_t *request)
360 unsigned int cmd, unsigned long arg )
361{ 515{
362 drm_file_t *priv = filp->private_data;
363 drm_device_t *dev = priv->head->dev;
364 drm_device_dma_t *dma = dev->dma; 516 drm_device_dma_t *dma = dev->dma;
365 drm_buf_desc_t request;
366 drm_buf_entry_t *entry; 517 drm_buf_entry_t *entry;
367 drm_buf_t *buf; 518 drm_buf_t *buf;
368 unsigned long offset; 519 unsigned long offset;
@@ -376,25 +527,20 @@ static int drm_addbufs_agp( struct inode *inode, struct file *filp,
376 int byte_count; 527 int byte_count;
377 int i; 528 int i;
378 drm_buf_t **temp_buflist; 529 drm_buf_t **temp_buflist;
379 drm_buf_desc_t __user *argp = (void __user *)arg;
380 530
381 if ( !dma ) return -EINVAL; 531 if ( !dma ) return -EINVAL;
382 532
383 if ( copy_from_user( &request, argp, 533 count = request->count;
384 sizeof(request) ) ) 534 order = drm_order(request->size);
385 return -EFAULT;
386
387 count = request.count;
388 order = drm_order( request.size );
389 size = 1 << order; 535 size = 1 << order;
390 536
391 alignment = (request.flags & _DRM_PAGE_ALIGN) 537 alignment = (request->flags & _DRM_PAGE_ALIGN)
392 ? PAGE_ALIGN(size) : size; 538 ? PAGE_ALIGN(size) : size;
393 page_order = order - PAGE_SHIFT > 0 ? order - PAGE_SHIFT : 0; 539 page_order = order - PAGE_SHIFT > 0 ? order - PAGE_SHIFT : 0;
394 total = PAGE_SIZE << page_order; 540 total = PAGE_SIZE << page_order;
395 541
396 byte_count = 0; 542 byte_count = 0;
397 agp_offset = dev->agp->base + request.agp_start; 543 agp_offset = dev->agp->base + request->agp_start;
398 544
399 DRM_DEBUG( "count: %d\n", count ); 545 DRM_DEBUG( "count: %d\n", count );
400 DRM_DEBUG( "order: %d\n", order ); 546 DRM_DEBUG( "order: %d\n", order );
@@ -508,26 +654,20 @@ static int drm_addbufs_agp( struct inode *inode, struct file *filp,
508 654
509 up( &dev->struct_sem ); 655 up( &dev->struct_sem );
510 656
511 request.count = entry->buf_count; 657 request->count = entry->buf_count;
512 request.size = size; 658 request->size = size;
513
514 if ( copy_to_user( argp, &request, sizeof(request) ) )
515 return -EFAULT;
516 659
517 dma->flags = _DRM_DMA_USE_AGP; 660 dma->flags = _DRM_DMA_USE_AGP;
518 661
519 atomic_dec( &dev->buf_alloc ); 662 atomic_dec( &dev->buf_alloc );
520 return 0; 663 return 0;
521} 664}
665EXPORT_SYMBOL(drm_addbufs_agp);
522#endif /* __OS_HAS_AGP */ 666#endif /* __OS_HAS_AGP */
523 667
524static int drm_addbufs_pci( struct inode *inode, struct file *filp, 668int drm_addbufs_pci(drm_device_t *dev, drm_buf_desc_t *request)
525 unsigned int cmd, unsigned long arg )
526{ 669{
527 drm_file_t *priv = filp->private_data;
528 drm_device_t *dev = priv->head->dev;
529 drm_device_dma_t *dma = dev->dma; 670 drm_device_dma_t *dma = dev->dma;
530 drm_buf_desc_t request;
531 int count; 671 int count;
532 int order; 672 int order;
533 int size; 673 int size;
@@ -543,26 +683,22 @@ static int drm_addbufs_pci( struct inode *inode, struct file *filp,
543 int page_count; 683 int page_count;
544 unsigned long *temp_pagelist; 684 unsigned long *temp_pagelist;
545 drm_buf_t **temp_buflist; 685 drm_buf_t **temp_buflist;
546 drm_buf_desc_t __user *argp = (void __user *)arg;
547 686
548 if (!drm_core_check_feature(dev, DRIVER_PCI_DMA)) return -EINVAL; 687 if (!drm_core_check_feature(dev, DRIVER_PCI_DMA)) return -EINVAL;
549 if ( !dma ) return -EINVAL; 688 if ( !dma ) return -EINVAL;
550 689
551 if ( copy_from_user( &request, argp, sizeof(request) ) ) 690 count = request->count;
552 return -EFAULT; 691 order = drm_order(request->size);
553
554 count = request.count;
555 order = drm_order( request.size );
556 size = 1 << order; 692 size = 1 << order;
557 693
558 DRM_DEBUG( "count=%d, size=%d (%d), order=%d, queue_count=%d\n", 694 DRM_DEBUG( "count=%d, size=%d (%d), order=%d, queue_count=%d\n",
559 request.count, request.size, size, 695 request->count, request->size, size,
560 order, dev->queue_count ); 696 order, dev->queue_count );
561 697
562 if ( order < DRM_MIN_ORDER || order > DRM_MAX_ORDER ) return -EINVAL; 698 if ( order < DRM_MIN_ORDER || order > DRM_MAX_ORDER ) return -EINVAL;
563 if ( dev->queue_count ) return -EBUSY; /* Not while in use */ 699 if ( dev->queue_count ) return -EBUSY; /* Not while in use */
564 700
565 alignment = (request.flags & _DRM_PAGE_ALIGN) 701 alignment = (request->flags & _DRM_PAGE_ALIGN)
566 ? PAGE_ALIGN(size) : size; 702 ? PAGE_ALIGN(size) : size;
567 page_order = order - PAGE_SHIFT > 0 ? order - PAGE_SHIFT : 0; 703 page_order = order - PAGE_SHIFT > 0 ? order - PAGE_SHIFT : 0;
568 total = PAGE_SIZE << page_order; 704 total = PAGE_SIZE << page_order;
@@ -740,25 +876,18 @@ static int drm_addbufs_pci( struct inode *inode, struct file *filp,
740 876
741 up( &dev->struct_sem ); 877 up( &dev->struct_sem );
742 878
743 request.count = entry->buf_count; 879 request->count = entry->buf_count;
744 request.size = size; 880 request->size = size;
745
746 if ( copy_to_user( argp, &request, sizeof(request) ) )
747 return -EFAULT;
748 881
749 atomic_dec( &dev->buf_alloc ); 882 atomic_dec( &dev->buf_alloc );
750 return 0; 883 return 0;
751 884
752} 885}
886EXPORT_SYMBOL(drm_addbufs_pci);
753 887
754static int drm_addbufs_sg( struct inode *inode, struct file *filp, 888static int drm_addbufs_sg(drm_device_t *dev, drm_buf_desc_t *request)
755 unsigned int cmd, unsigned long arg )
756{ 889{
757 drm_file_t *priv = filp->private_data;
758 drm_device_t *dev = priv->head->dev;
759 drm_device_dma_t *dma = dev->dma; 890 drm_device_dma_t *dma = dev->dma;
760 drm_buf_desc_t __user *argp = (void __user *)arg;
761 drm_buf_desc_t request;
762 drm_buf_entry_t *entry; 891 drm_buf_entry_t *entry;
763 drm_buf_t *buf; 892 drm_buf_t *buf;
764 unsigned long offset; 893 unsigned long offset;
@@ -777,20 +906,17 @@ static int drm_addbufs_sg( struct inode *inode, struct file *filp,
777 906
778 if ( !dma ) return -EINVAL; 907 if ( !dma ) return -EINVAL;
779 908
780 if ( copy_from_user( &request, argp, sizeof(request) ) ) 909 count = request->count;
781 return -EFAULT; 910 order = drm_order(request->size);
782
783 count = request.count;
784 order = drm_order( request.size );
785 size = 1 << order; 911 size = 1 << order;
786 912
787 alignment = (request.flags & _DRM_PAGE_ALIGN) 913 alignment = (request->flags & _DRM_PAGE_ALIGN)
788 ? PAGE_ALIGN(size) : size; 914 ? PAGE_ALIGN(size) : size;
789 page_order = order - PAGE_SHIFT > 0 ? order - PAGE_SHIFT : 0; 915 page_order = order - PAGE_SHIFT > 0 ? order - PAGE_SHIFT : 0;
790 total = PAGE_SIZE << page_order; 916 total = PAGE_SIZE << page_order;
791 917
792 byte_count = 0; 918 byte_count = 0;
793 agp_offset = request.agp_start; 919 agp_offset = request->agp_start;
794 920
795 DRM_DEBUG( "count: %d\n", count ); 921 DRM_DEBUG( "count: %d\n", count );
796 DRM_DEBUG( "order: %d\n", order ); 922 DRM_DEBUG( "order: %d\n", order );
@@ -848,7 +974,8 @@ static int drm_addbufs_sg( struct inode *inode, struct file *filp,
848 974
849 buf->offset = (dma->byte_count + offset); 975 buf->offset = (dma->byte_count + offset);
850 buf->bus_address = agp_offset + offset; 976 buf->bus_address = agp_offset + offset;
851 buf->address = (void *)(agp_offset + offset + dev->sg->handle); 977 buf->address = (void *)(agp_offset + offset
978 + (unsigned long)dev->sg->virtual);
852 buf->next = NULL; 979 buf->next = NULL;
853 buf->waiting = 0; 980 buf->waiting = 0;
854 buf->pending = 0; 981 buf->pending = 0;
@@ -905,11 +1032,8 @@ static int drm_addbufs_sg( struct inode *inode, struct file *filp,
905 1032
906 up( &dev->struct_sem ); 1033 up( &dev->struct_sem );
907 1034
908 request.count = entry->buf_count; 1035 request->count = entry->buf_count;
909 request.size = size; 1036 request->size = size;
910
911 if ( copy_to_user( argp, &request, sizeof(request) ) )
912 return -EFAULT;
913 1037
914 dma->flags = _DRM_DMA_USE_SG; 1038 dma->flags = _DRM_DMA_USE_SG;
915 1039
@@ -917,6 +1041,161 @@ static int drm_addbufs_sg( struct inode *inode, struct file *filp,
917 return 0; 1041 return 0;
918} 1042}
919 1043
1044int drm_addbufs_fb(drm_device_t *dev, drm_buf_desc_t *request)
1045{
1046 drm_device_dma_t *dma = dev->dma;
1047 drm_buf_entry_t *entry;
1048 drm_buf_t *buf;
1049 unsigned long offset;
1050 unsigned long agp_offset;
1051 int count;
1052 int order;
1053 int size;
1054 int alignment;
1055 int page_order;
1056 int total;
1057 int byte_count;
1058 int i;
1059 drm_buf_t **temp_buflist;
1060
1061 if (!drm_core_check_feature(dev, DRIVER_FB_DMA))
1062 return -EINVAL;
1063
1064 if (!dma)
1065 return -EINVAL;
1066
1067 count = request->count;
1068 order = drm_order(request->size);
1069 size = 1 << order;
1070
1071 alignment = (request->flags & _DRM_PAGE_ALIGN)
1072 ? PAGE_ALIGN(size) : size;
1073 page_order = order - PAGE_SHIFT > 0 ? order - PAGE_SHIFT : 0;
1074 total = PAGE_SIZE << page_order;
1075
1076 byte_count = 0;
1077 agp_offset = request->agp_start;
1078
1079 DRM_DEBUG("count: %d\n", count);
1080 DRM_DEBUG("order: %d\n", order);
1081 DRM_DEBUG("size: %d\n", size);
1082 DRM_DEBUG("agp_offset: %lu\n", agp_offset);
1083 DRM_DEBUG("alignment: %d\n", alignment);
1084 DRM_DEBUG("page_order: %d\n", page_order);
1085 DRM_DEBUG("total: %d\n", total);
1086
1087 if (order < DRM_MIN_ORDER || order > DRM_MAX_ORDER)
1088 return -EINVAL;
1089 if (dev->queue_count)
1090 return -EBUSY; /* Not while in use */
1091
1092 spin_lock(&dev->count_lock);
1093 if (dev->buf_use) {
1094 spin_unlock(&dev->count_lock);
1095 return -EBUSY;
1096 }
1097 atomic_inc(&dev->buf_alloc);
1098 spin_unlock(&dev->count_lock);
1099
1100 down(&dev->struct_sem);
1101 entry = &dma->bufs[order];
1102 if (entry->buf_count) {
1103 up(&dev->struct_sem);
1104 atomic_dec(&dev->buf_alloc);
1105 return -ENOMEM; /* May only call once for each order */
1106 }
1107
1108 if (count < 0 || count > 4096) {
1109 up(&dev->struct_sem);
1110 atomic_dec(&dev->buf_alloc);
1111 return -EINVAL;
1112 }
1113
1114 entry->buflist = drm_alloc(count * sizeof(*entry->buflist),
1115 DRM_MEM_BUFS);
1116 if (!entry->buflist) {
1117 up(&dev->struct_sem);
1118 atomic_dec(&dev->buf_alloc);
1119 return -ENOMEM;
1120 }
1121 memset(entry->buflist, 0, count * sizeof(*entry->buflist));
1122
1123 entry->buf_size = size;
1124 entry->page_order = page_order;
1125
1126 offset = 0;
1127
1128 while (entry->buf_count < count) {
1129 buf = &entry->buflist[entry->buf_count];
1130 buf->idx = dma->buf_count + entry->buf_count;
1131 buf->total = alignment;
1132 buf->order = order;
1133 buf->used = 0;
1134
1135 buf->offset = (dma->byte_count + offset);
1136 buf->bus_address = agp_offset + offset;
1137 buf->address = (void *)(agp_offset + offset);
1138 buf->next = NULL;
1139 buf->waiting = 0;
1140 buf->pending = 0;
1141 init_waitqueue_head(&buf->dma_wait);
1142 buf->filp = NULL;
1143
1144 buf->dev_priv_size = dev->driver->dev_priv_size;
1145 buf->dev_private = drm_alloc(buf->dev_priv_size, DRM_MEM_BUFS);
1146 if (!buf->dev_private) {
1147 /* Set count correctly so we free the proper amount. */
1148 entry->buf_count = count;
1149 drm_cleanup_buf_error(dev, entry);
1150 up(&dev->struct_sem);
1151 atomic_dec(&dev->buf_alloc);
1152 return -ENOMEM;
1153 }
1154 memset(buf->dev_private, 0, buf->dev_priv_size);
1155
1156 DRM_DEBUG("buffer %d @ %p\n", entry->buf_count, buf->address);
1157
1158 offset += alignment;
1159 entry->buf_count++;
1160 byte_count += PAGE_SIZE << page_order;
1161 }
1162
1163 DRM_DEBUG("byte_count: %d\n", byte_count);
1164
1165 temp_buflist = drm_realloc(dma->buflist,
1166 dma->buf_count * sizeof(*dma->buflist),
1167 (dma->buf_count + entry->buf_count)
1168 * sizeof(*dma->buflist), DRM_MEM_BUFS);
1169 if (!temp_buflist) {
1170 /* Free the entry because it isn't valid */
1171 drm_cleanup_buf_error(dev, entry);
1172 up(&dev->struct_sem);
1173 atomic_dec(&dev->buf_alloc);
1174 return -ENOMEM;
1175 }
1176 dma->buflist = temp_buflist;
1177
1178 for (i = 0; i < entry->buf_count; i++) {
1179 dma->buflist[i + dma->buf_count] = &entry->buflist[i];
1180 }
1181
1182 dma->buf_count += entry->buf_count;
1183 dma->byte_count += byte_count;
1184
1185 DRM_DEBUG("dma->buf_count : %d\n", dma->buf_count);
1186 DRM_DEBUG("entry->buf_count : %d\n", entry->buf_count);
1187
1188 up(&dev->struct_sem);
1189
1190 request->count = entry->buf_count;
1191 request->size = size;
1192
1193 dma->flags = _DRM_DMA_USE_FB;
1194
1195 atomic_dec(&dev->buf_alloc);
1196 return 0;
1197}
1198
920/** 1199/**
921 * Add buffers for DMA transfers (ioctl). 1200 * Add buffers for DMA transfers (ioctl).
922 * 1201 *
@@ -937,6 +1216,7 @@ int drm_addbufs( struct inode *inode, struct file *filp,
937 drm_buf_desc_t request; 1216 drm_buf_desc_t request;
938 drm_file_t *priv = filp->private_data; 1217 drm_file_t *priv = filp->private_data;
939 drm_device_t *dev = priv->head->dev; 1218 drm_device_t *dev = priv->head->dev;
1219 int ret;
940 1220
941 if (!drm_core_check_feature(dev, DRIVER_HAVE_DMA)) 1221 if (!drm_core_check_feature(dev, DRIVER_HAVE_DMA))
942 return -EINVAL; 1222 return -EINVAL;
@@ -947,13 +1227,23 @@ int drm_addbufs( struct inode *inode, struct file *filp,
947 1227
948#if __OS_HAS_AGP 1228#if __OS_HAS_AGP
949 if ( request.flags & _DRM_AGP_BUFFER ) 1229 if ( request.flags & _DRM_AGP_BUFFER )
950 return drm_addbufs_agp( inode, filp, cmd, arg ); 1230 ret=drm_addbufs_agp(dev, &request);
951 else 1231 else
952#endif 1232#endif
953 if ( request.flags & _DRM_SG_BUFFER ) 1233 if ( request.flags & _DRM_SG_BUFFER )
954 return drm_addbufs_sg( inode, filp, cmd, arg ); 1234 ret=drm_addbufs_sg(dev, &request);
1235 else if ( request.flags & _DRM_FB_BUFFER)
1236 ret=drm_addbufs_fb(dev, &request);
955 else 1237 else
956 return drm_addbufs_pci( inode, filp, cmd, arg ); 1238 ret=drm_addbufs_pci(dev, &request);
1239
1240 if (ret==0) {
1241 if (copy_to_user((void __user *)arg, &request,
1242 sizeof(request))) {
1243 ret = -EFAULT;
1244 }
1245 }
1246 return ret;
957} 1247}
958 1248
959 1249
@@ -1196,43 +1486,31 @@ int drm_mapbufs( struct inode *inode, struct file *filp,
1196 return -EFAULT; 1486 return -EFAULT;
1197 1487
1198 if ( request.count >= dma->buf_count ) { 1488 if ( request.count >= dma->buf_count ) {
1199 if ((drm_core_has_AGP(dev) && (dma->flags & _DRM_DMA_USE_AGP)) || 1489 if ((drm_core_has_AGP(dev) && (dma->flags & _DRM_DMA_USE_AGP))
1200 (drm_core_check_feature(dev, DRIVER_SG) && (dma->flags & _DRM_DMA_USE_SG)) ) { 1490 || (drm_core_check_feature(dev, DRIVER_SG)
1491 && (dma->flags & _DRM_DMA_USE_SG))
1492 || (drm_core_check_feature(dev, DRIVER_FB_DMA)
1493 && (dma->flags & _DRM_DMA_USE_FB))) {
1201 drm_map_t *map = dev->agp_buffer_map; 1494 drm_map_t *map = dev->agp_buffer_map;
1495 unsigned long token = dev->agp_buffer_token;
1202 1496
1203 if ( !map ) { 1497 if ( !map ) {
1204 retcode = -EINVAL; 1498 retcode = -EINVAL;
1205 goto done; 1499 goto done;
1206 } 1500 }
1207 1501
1208#if LINUX_VERSION_CODE <= 0x020402
1209 down( &current->mm->mmap_sem );
1210#else
1211 down_write( &current->mm->mmap_sem ); 1502 down_write( &current->mm->mmap_sem );
1212#endif
1213 virtual = do_mmap( filp, 0, map->size, 1503 virtual = do_mmap( filp, 0, map->size,
1214 PROT_READ | PROT_WRITE, 1504 PROT_READ | PROT_WRITE,
1215 MAP_SHARED, 1505 MAP_SHARED,
1216 (unsigned long)map->offset ); 1506 token );
1217#if LINUX_VERSION_CODE <= 0x020402
1218 up( &current->mm->mmap_sem );
1219#else
1220 up_write( &current->mm->mmap_sem ); 1507 up_write( &current->mm->mmap_sem );
1221#endif
1222 } else { 1508 } else {
1223#if LINUX_VERSION_CODE <= 0x020402
1224 down( &current->mm->mmap_sem );
1225#else
1226 down_write( &current->mm->mmap_sem ); 1509 down_write( &current->mm->mmap_sem );
1227#endif
1228 virtual = do_mmap( filp, 0, dma->byte_count, 1510 virtual = do_mmap( filp, 0, dma->byte_count,
1229 PROT_READ | PROT_WRITE, 1511 PROT_READ | PROT_WRITE,
1230 MAP_SHARED, 0 ); 1512 MAP_SHARED, 0 );
1231#if LINUX_VERSION_CODE <= 0x020402
1232 up( &current->mm->mmap_sem );
1233#else
1234 up_write( &current->mm->mmap_sem ); 1513 up_write( &current->mm->mmap_sem );
1235#endif
1236 } 1514 }
1237 if ( virtual > -1024UL ) { 1515 if ( virtual > -1024UL ) {
1238 /* Real error */ 1516 /* Real error */
@@ -1279,3 +1557,26 @@ int drm_mapbufs( struct inode *inode, struct file *filp,
1279 return retcode; 1557 return retcode;
1280} 1558}
1281 1559
1560/**
1561 * Compute size order. Returns the exponent of the smaller power of two which
1562 * is greater or equal to given number.
1563 *
1564 * \param size size.
1565 * \return order.
1566 *
1567 * \todo Can be made faster.
1568 */
1569int drm_order( unsigned long size )
1570{
1571 int order;
1572 unsigned long tmp;
1573
1574 for (order = 0, tmp = size >> 1; tmp; tmp >>= 1, order++)
1575 ;
1576
1577 if (size & (size - 1))
1578 ++order;
1579
1580 return order;
1581}
1582EXPORT_SYMBOL(drm_order);
diff --git a/drivers/char/drm/drm_context.c b/drivers/char/drm/drm_context.c
index a7cfabd1ca2e..f515567e5b6f 100644
--- a/drivers/char/drm/drm_context.c
+++ b/drivers/char/drm/drm_context.c
@@ -212,6 +212,7 @@ int drm_getsareactx(struct inode *inode, struct file *filp,
212 drm_ctx_priv_map_t __user *argp = (void __user *)arg; 212 drm_ctx_priv_map_t __user *argp = (void __user *)arg;
213 drm_ctx_priv_map_t request; 213 drm_ctx_priv_map_t request;
214 drm_map_t *map; 214 drm_map_t *map;
215 drm_map_list_t *_entry;
215 216
216 if (copy_from_user(&request, argp, sizeof(request))) 217 if (copy_from_user(&request, argp, sizeof(request)))
217 return -EFAULT; 218 return -EFAULT;
@@ -225,7 +226,17 @@ int drm_getsareactx(struct inode *inode, struct file *filp,
225 map = dev->context_sareas[request.ctx_id]; 226 map = dev->context_sareas[request.ctx_id];
226 up(&dev->struct_sem); 227 up(&dev->struct_sem);
227 228
228 request.handle = (void *) map->offset; 229 request.handle = 0;
230 list_for_each_entry(_entry, &dev->maplist->head,head) {
231 if (_entry->map == map) {
232 request.handle = (void *)(unsigned long)_entry->user_token;
233 break;
234 }
235 }
236 if (request.handle == 0)
237 return -EINVAL;
238
239
229 if (copy_to_user(argp, &request, sizeof(request))) 240 if (copy_to_user(argp, &request, sizeof(request)))
230 return -EFAULT; 241 return -EFAULT;
231 return 0; 242 return 0;
@@ -262,7 +273,7 @@ int drm_setsareactx(struct inode *inode, struct file *filp,
262 list_for_each(list, &dev->maplist->head) { 273 list_for_each(list, &dev->maplist->head) {
263 r_list = list_entry(list, drm_map_list_t, head); 274 r_list = list_entry(list, drm_map_list_t, head);
264 if (r_list->map 275 if (r_list->map
265 && r_list->map->offset == (unsigned long) request.handle) 276 && r_list->user_token == (unsigned long) request.handle)
266 goto found; 277 goto found;
267 } 278 }
268bad: 279bad:
@@ -369,7 +380,7 @@ int drm_resctx( struct inode *inode, struct file *filp,
369 for ( i = 0 ; i < DRM_RESERVED_CONTEXTS ; i++ ) { 380 for ( i = 0 ; i < DRM_RESERVED_CONTEXTS ; i++ ) {
370 ctx.handle = i; 381 ctx.handle = i;
371 if ( copy_to_user( &res.contexts[i], 382 if ( copy_to_user( &res.contexts[i],
372 &i, sizeof(i) ) ) 383 &ctx, sizeof(ctx) ) )
373 return -EFAULT; 384 return -EFAULT;
374 } 385 }
375 } 386 }
diff --git a/drivers/char/drm/drm_drv.c b/drivers/char/drm/drm_drv.c
index 3333c250c4d9..6ba48f346fcf 100644
--- a/drivers/char/drm/drm_drv.c
+++ b/drivers/char/drm/drm_drv.c
@@ -70,8 +70,8 @@ static drm_ioctl_desc_t drm_ioctls[] = {
70 [DRM_IOCTL_NR(DRM_IOCTL_UNBLOCK)] = { drm_noop, 1, 1 }, 70 [DRM_IOCTL_NR(DRM_IOCTL_UNBLOCK)] = { drm_noop, 1, 1 },
71 [DRM_IOCTL_NR(DRM_IOCTL_AUTH_MAGIC)] = { drm_authmagic, 1, 1 }, 71 [DRM_IOCTL_NR(DRM_IOCTL_AUTH_MAGIC)] = { drm_authmagic, 1, 1 },
72 72
73 [DRM_IOCTL_NR(DRM_IOCTL_ADD_MAP)] = { drm_addmap, 1, 1 }, 73 [DRM_IOCTL_NR(DRM_IOCTL_ADD_MAP)] = { drm_addmap_ioctl,1, 1 },
74 [DRM_IOCTL_NR(DRM_IOCTL_RM_MAP)] = { drm_rmmap, 1, 0 }, 74 [DRM_IOCTL_NR(DRM_IOCTL_RM_MAP)] = { drm_rmmap_ioctl, 1, 0 },
75 75
76 [DRM_IOCTL_NR(DRM_IOCTL_SET_SAREA_CTX)] = { drm_setsareactx, 1, 1 }, 76 [DRM_IOCTL_NR(DRM_IOCTL_SET_SAREA_CTX)] = { drm_setsareactx, 1, 1 },
77 [DRM_IOCTL_NR(DRM_IOCTL_GET_SAREA_CTX)] = { drm_getsareactx, 1, 0 }, 77 [DRM_IOCTL_NR(DRM_IOCTL_GET_SAREA_CTX)] = { drm_getsareactx, 1, 0 },
@@ -102,10 +102,10 @@ static drm_ioctl_desc_t drm_ioctls[] = {
102 [DRM_IOCTL_NR(DRM_IOCTL_CONTROL)] = { drm_control, 1, 1 }, 102 [DRM_IOCTL_NR(DRM_IOCTL_CONTROL)] = { drm_control, 1, 1 },
103 103
104#if __OS_HAS_AGP 104#if __OS_HAS_AGP
105 [DRM_IOCTL_NR(DRM_IOCTL_AGP_ACQUIRE)] = { drm_agp_acquire, 1, 1 }, 105 [DRM_IOCTL_NR(DRM_IOCTL_AGP_ACQUIRE)] = { drm_agp_acquire_ioctl, 1, 1 },
106 [DRM_IOCTL_NR(DRM_IOCTL_AGP_RELEASE)] = { drm_agp_release, 1, 1 }, 106 [DRM_IOCTL_NR(DRM_IOCTL_AGP_RELEASE)] = { drm_agp_release_ioctl, 1, 1 },
107 [DRM_IOCTL_NR(DRM_IOCTL_AGP_ENABLE)] = { drm_agp_enable, 1, 1 }, 107 [DRM_IOCTL_NR(DRM_IOCTL_AGP_ENABLE)] = { drm_agp_enable_ioctl, 1, 1 },
108 [DRM_IOCTL_NR(DRM_IOCTL_AGP_INFO)] = { drm_agp_info, 1, 0 }, 108 [DRM_IOCTL_NR(DRM_IOCTL_AGP_INFO)] = { drm_agp_info_ioctl, 1, 0 },
109 [DRM_IOCTL_NR(DRM_IOCTL_AGP_ALLOC)] = { drm_agp_alloc, 1, 1 }, 109 [DRM_IOCTL_NR(DRM_IOCTL_AGP_ALLOC)] = { drm_agp_alloc, 1, 1 },
110 [DRM_IOCTL_NR(DRM_IOCTL_AGP_FREE)] = { drm_agp_free, 1, 1 }, 110 [DRM_IOCTL_NR(DRM_IOCTL_AGP_FREE)] = { drm_agp_free, 1, 1 },
111 [DRM_IOCTL_NR(DRM_IOCTL_AGP_BIND)] = { drm_agp_bind, 1, 1 }, 111 [DRM_IOCTL_NR(DRM_IOCTL_AGP_BIND)] = { drm_agp_bind, 1, 1 },
@@ -127,14 +127,12 @@ static drm_ioctl_desc_t drm_ioctls[] = {
127 * 127 *
128 * Frees every resource in \p dev. 128 * Frees every resource in \p dev.
129 * 129 *
130 * \sa drm_device and setup(). 130 * \sa drm_device
131 */ 131 */
132int drm_takedown( drm_device_t *dev ) 132int drm_takedown( drm_device_t *dev )
133{ 133{
134 drm_magic_entry_t *pt, *next; 134 drm_magic_entry_t *pt, *next;
135 drm_map_t *map;
136 drm_map_list_t *r_list; 135 drm_map_list_t *r_list;
137 struct list_head *list, *list_next;
138 drm_vma_entry_t *vma, *vma_next; 136 drm_vma_entry_t *vma, *vma_next;
139 int i; 137 int i;
140 138
@@ -142,6 +140,7 @@ int drm_takedown( drm_device_t *dev )
142 140
143 if (dev->driver->pretakedown) 141 if (dev->driver->pretakedown)
144 dev->driver->pretakedown(dev); 142 dev->driver->pretakedown(dev);
143 DRM_DEBUG("driver pretakedown completed\n");
145 144
146 if (dev->unique) { 145 if (dev->unique) {
147 drm_free(dev->unique, strlen(dev->unique) + 1, DRM_MEM_DRIVER); 146 drm_free(dev->unique, strlen(dev->unique) + 1, DRM_MEM_DRIVER);
@@ -178,11 +177,16 @@ int drm_takedown( drm_device_t *dev )
178 } 177 }
179 dev->agp->memory = NULL; 178 dev->agp->memory = NULL;
180 179
181 if ( dev->agp->acquired ) drm_agp_do_release(dev); 180 if (dev->agp->acquired)
181 drm_agp_release(dev);
182 182
183 dev->agp->acquired = 0; 183 dev->agp->acquired = 0;
184 dev->agp->enabled = 0; 184 dev->agp->enabled = 0;
185 } 185 }
186 if (drm_core_check_feature(dev, DRIVER_SG) && dev->sg) {
187 drm_sg_cleanup(dev->sg);
188 dev->sg = NULL;
189 }
186 190
187 /* Clear vma list (only built for debugging) */ 191 /* Clear vma list (only built for debugging) */
188 if ( dev->vmalist ) { 192 if ( dev->vmalist ) {
@@ -194,48 +198,11 @@ int drm_takedown( drm_device_t *dev )
194 } 198 }
195 199
196 if( dev->maplist ) { 200 if( dev->maplist ) {
197 list_for_each_safe( list, list_next, &dev->maplist->head ) { 201 while (!list_empty(&dev->maplist->head)) {
198 r_list = (drm_map_list_t *)list; 202 struct list_head *list = dev->maplist->head.next;
199 203 r_list = list_entry(list, drm_map_list_t, head);
200 if ( ( map = r_list->map ) ) { 204 drm_rmmap_locked(dev, r_list->map);
201 switch ( map->type ) { 205 }
202 case _DRM_REGISTERS:
203 case _DRM_FRAME_BUFFER:
204 if (drm_core_has_MTRR(dev)) {
205 if ( map->mtrr >= 0 ) {
206 int retcode;
207 retcode = mtrr_del( map->mtrr,
208 map->offset,
209 map->size );
210 DRM_DEBUG( "mtrr_del=%d\n", retcode );
211 }
212 }
213 drm_ioremapfree( map->handle, map->size, dev );
214 break;
215 case _DRM_SHM:
216 vfree(map->handle);
217 break;
218
219 case _DRM_AGP:
220 /* Do nothing here, because this is all
221 * handled in the AGP/GART driver.
222 */
223 break;
224 case _DRM_SCATTER_GATHER:
225 /* Handle it */
226 if (drm_core_check_feature(dev, DRIVER_SG) && dev->sg) {
227 drm_sg_cleanup(dev->sg);
228 dev->sg = NULL;
229 }
230 break;
231 }
232 drm_free(map, sizeof(*map), DRM_MEM_MAPS);
233 }
234 list_del( list );
235 drm_free(r_list, sizeof(*r_list), DRM_MEM_MAPS);
236 }
237 drm_free(dev->maplist, sizeof(*dev->maplist), DRM_MEM_MAPS);
238 dev->maplist = NULL;
239 } 206 }
240 207
241 if (drm_core_check_feature(dev, DRIVER_DMA_QUEUE) && dev->queuelist ) { 208 if (drm_core_check_feature(dev, DRIVER_DMA_QUEUE) && dev->queuelist ) {
@@ -264,6 +231,7 @@ int drm_takedown( drm_device_t *dev )
264 } 231 }
265 up( &dev->struct_sem ); 232 up( &dev->struct_sem );
266 233
234 DRM_DEBUG("takedown completed\n");
267 return 0; 235 return 0;
268} 236}
269 237
@@ -312,7 +280,7 @@ EXPORT_SYMBOL(drm_init);
312 * 280 *
313 * Cleans up all DRM device, calling takedown(). 281 * Cleans up all DRM device, calling takedown().
314 * 282 *
315 * \sa drm_init(). 283 * \sa drm_init
316 */ 284 */
317static void drm_cleanup( drm_device_t *dev ) 285static void drm_cleanup( drm_device_t *dev )
318{ 286{
@@ -325,6 +293,11 @@ static void drm_cleanup( drm_device_t *dev )
325 293
326 drm_takedown( dev ); 294 drm_takedown( dev );
327 295
296 if (dev->maplist) {
297 drm_free(dev->maplist, sizeof(*dev->maplist), DRM_MEM_MAPS);
298 dev->maplist = NULL;
299 }
300
328 drm_ctxbitmap_cleanup( dev ); 301 drm_ctxbitmap_cleanup( dev );
329 302
330 if (drm_core_has_MTRR(dev) && drm_core_has_AGP(dev) && 303 if (drm_core_has_MTRR(dev) && drm_core_has_AGP(dev) &&
diff --git a/drivers/char/drm/drm_fops.c b/drivers/char/drm/drm_fops.c
index 10e64fde8d78..a1f4e9cd64ed 100644
--- a/drivers/char/drm/drm_fops.c
+++ b/drivers/char/drm/drm_fops.c
@@ -71,12 +71,6 @@ static int drm_setup( drm_device_t *dev )
71 dev->magiclist[i].tail = NULL; 71 dev->magiclist[i].tail = NULL;
72 } 72 }
73 73
74 dev->maplist = drm_alloc(sizeof(*dev->maplist),
75 DRM_MEM_MAPS);
76 if(dev->maplist == NULL) return -ENOMEM;
77 memset(dev->maplist, 0, sizeof(*dev->maplist));
78 INIT_LIST_HEAD(&dev->maplist->head);
79
80 dev->ctxlist = drm_alloc(sizeof(*dev->ctxlist), 74 dev->ctxlist = drm_alloc(sizeof(*dev->ctxlist),
81 DRM_MEM_CTXLIST); 75 DRM_MEM_CTXLIST);
82 if(dev->ctxlist == NULL) return -ENOMEM; 76 if(dev->ctxlist == NULL) return -ENOMEM;
diff --git a/drivers/char/drm/drm_ioctl.c b/drivers/char/drm/drm_ioctl.c
index 39afda0ccabe..d2ed3ba5aca9 100644
--- a/drivers/char/drm/drm_ioctl.c
+++ b/drivers/char/drm/drm_ioctl.c
@@ -208,7 +208,7 @@ int drm_getmap( struct inode *inode, struct file *filp,
208 map.size = r_list->map->size; 208 map.size = r_list->map->size;
209 map.type = r_list->map->type; 209 map.type = r_list->map->type;
210 map.flags = r_list->map->flags; 210 map.flags = r_list->map->flags;
211 map.handle = r_list->map->handle; 211 map.handle = (void *)(unsigned long) r_list->user_token;
212 map.mtrr = r_list->map->mtrr; 212 map.mtrr = r_list->map->mtrr;
213 up(&dev->struct_sem); 213 up(&dev->struct_sem);
214 214
diff --git a/drivers/char/drm/drm_memory.c b/drivers/char/drm/drm_memory.c
index ace3d42f4407..ff483fb418aa 100644
--- a/drivers/char/drm/drm_memory.c
+++ b/drivers/char/drm/drm_memory.c
@@ -142,27 +142,31 @@ void drm_free_pages(unsigned long address, int order, int area)
142 142
143#if __OS_HAS_AGP 143#if __OS_HAS_AGP
144/** Wrapper around agp_allocate_memory() */ 144/** Wrapper around agp_allocate_memory() */
145DRM_AGP_MEM *drm_alloc_agp(struct agp_bridge_data *bridge, int pages, u32 type) 145DRM_AGP_MEM *drm_alloc_agp(drm_device_t *dev, int pages, u32 type)
146{ 146{
147 return drm_agp_allocate_memory(bridge, pages, type); 147 return drm_agp_allocate_memory(dev->agp->bridge, pages, type);
148} 148}
149EXPORT_SYMBOL(drm_alloc_agp);
149 150
150/** Wrapper around agp_free_memory() */ 151/** Wrapper around agp_free_memory() */
151int drm_free_agp(DRM_AGP_MEM *handle, int pages) 152int drm_free_agp(DRM_AGP_MEM *handle, int pages)
152{ 153{
153 return drm_agp_free_memory(handle) ? 0 : -EINVAL; 154 return drm_agp_free_memory(handle) ? 0 : -EINVAL;
154} 155}
156EXPORT_SYMBOL(drm_free_agp);
155 157
156/** Wrapper around agp_bind_memory() */ 158/** Wrapper around agp_bind_memory() */
157int drm_bind_agp(DRM_AGP_MEM *handle, unsigned int start) 159int drm_bind_agp(DRM_AGP_MEM *handle, unsigned int start)
158{ 160{
159 return drm_agp_bind_memory(handle, start); 161 return drm_agp_bind_memory(handle, start);
160} 162}
163EXPORT_SYMBOL(drm_bind_agp);
161 164
162/** Wrapper around agp_unbind_memory() */ 165/** Wrapper around agp_unbind_memory() */
163int drm_unbind_agp(DRM_AGP_MEM *handle) 166int drm_unbind_agp(DRM_AGP_MEM *handle)
164{ 167{
165 return drm_agp_unbind_memory(handle); 168 return drm_agp_unbind_memory(handle);
166} 169}
170EXPORT_SYMBOL(drm_unbind_agp);
167#endif /* agp */ 171#endif /* agp */
168#endif /* debug_memory */ 172#endif /* debug_memory */
diff --git a/drivers/char/drm/drm_pci.c b/drivers/char/drm/drm_pci.c
index 192e8762571c..09ed712c1a7f 100644
--- a/drivers/char/drm/drm_pci.c
+++ b/drivers/char/drm/drm_pci.c
@@ -46,11 +46,11 @@
46/** 46/**
47 * \brief Allocate a PCI consistent memory block, for DMA. 47 * \brief Allocate a PCI consistent memory block, for DMA.
48 */ 48 */
49void *drm_pci_alloc(drm_device_t * dev, size_t size, size_t align, 49drm_dma_handle_t *drm_pci_alloc(drm_device_t * dev, size_t size, size_t align,
50 dma_addr_t maxaddr, dma_addr_t * busaddr) 50 dma_addr_t maxaddr)
51{ 51{
52 void *address; 52 drm_dma_handle_t *dmah;
53#if DRM_DEBUG_MEMORY 53#ifdef DRM_DEBUG_MEMORY
54 int area = DRM_MEM_DMA; 54 int area = DRM_MEM_DMA;
55 55
56 spin_lock(&drm_mem_lock); 56 spin_lock(&drm_mem_lock);
@@ -74,13 +74,19 @@ void *drm_pci_alloc(drm_device_t * dev, size_t size, size_t align,
74 return NULL; 74 return NULL;
75 } 75 }
76 76
77 address = pci_alloc_consistent(dev->pdev, size, busaddr); 77 dmah = kmalloc(sizeof(drm_dma_handle_t), GFP_KERNEL);
78 if (!dmah)
79 return NULL;
80
81 dmah->size = size;
82 dmah->vaddr = pci_alloc_consistent(dev->pdev, size, &dmah->busaddr);
78 83
79#if DRM_DEBUG_MEMORY 84#ifdef DRM_DEBUG_MEMORY
80 if (address == NULL) { 85 if (dmah->vaddr == NULL) {
81 spin_lock(&drm_mem_lock); 86 spin_lock(&drm_mem_lock);
82 ++drm_mem_stats[area].fail_count; 87 ++drm_mem_stats[area].fail_count;
83 spin_unlock(&drm_mem_lock); 88 spin_unlock(&drm_mem_lock);
89 kfree(dmah);
84 return NULL; 90 return NULL;
85 } 91 }
86 92
@@ -90,37 +96,42 @@ void *drm_pci_alloc(drm_device_t * dev, size_t size, size_t align,
90 drm_ram_used += size; 96 drm_ram_used += size;
91 spin_unlock(&drm_mem_lock); 97 spin_unlock(&drm_mem_lock);
92#else 98#else
93 if (address == NULL) 99 if (dmah->vaddr == NULL) {
100 kfree(dmah);
94 return NULL; 101 return NULL;
102 }
95#endif 103#endif
96 104
97 memset(address, 0, size); 105 memset(dmah->vaddr, 0, size);
98 106
99 return address; 107 return dmah;
100} 108}
101EXPORT_SYMBOL(drm_pci_alloc); 109EXPORT_SYMBOL(drm_pci_alloc);
102 110
103/** 111/**
104 * \brief Free a PCI consistent memory block. 112 * \brief Free a PCI consistent memory block with freeing its descriptor.
113 *
114 * This function is for internal use in the Linux-specific DRM core code.
105 */ 115 */
106void 116void
107drm_pci_free(drm_device_t * dev, size_t size, void *vaddr, dma_addr_t busaddr) 117__drm_pci_free(drm_device_t * dev, drm_dma_handle_t *dmah)
108{ 118{
109#if DRM_DEBUG_MEMORY 119#ifdef DRM_DEBUG_MEMORY
110 int area = DRM_MEM_DMA; 120 int area = DRM_MEM_DMA;
111 int alloc_count; 121 int alloc_count;
112 int free_count; 122 int free_count;
113#endif 123#endif
114 124
115 if (!vaddr) { 125 if (!dmah->vaddr) {
116#if DRM_DEBUG_MEMORY 126#ifdef DRM_DEBUG_MEMORY
117 DRM_MEM_ERROR(area, "Attempt to free address 0\n"); 127 DRM_MEM_ERROR(area, "Attempt to free address 0\n");
118#endif 128#endif
119 } else { 129 } else {
120 pci_free_consistent(dev->pdev, size, vaddr, busaddr); 130 pci_free_consistent(dev->pdev, dmah->size, dmah->vaddr,
131 dmah->busaddr);
121 } 132 }
122 133
123#if DRM_DEBUG_MEMORY 134#ifdef DRM_DEBUG_MEMORY
124 spin_lock(&drm_mem_lock); 135 spin_lock(&drm_mem_lock);
125 free_count = ++drm_mem_stats[area].free_count; 136 free_count = ++drm_mem_stats[area].free_count;
126 alloc_count = drm_mem_stats[area].succeed_count; 137 alloc_count = drm_mem_stats[area].succeed_count;
@@ -135,6 +146,16 @@ drm_pci_free(drm_device_t * dev, size_t size, void *vaddr, dma_addr_t busaddr)
135#endif 146#endif
136 147
137} 148}
149
150/**
151 * \brief Free a PCI consistent memory block
152 */
153void
154drm_pci_free(drm_device_t *dev, drm_dma_handle_t *dmah)
155{
156 __drm_pci_free(dev, dmah);
157 kfree(dmah);
158}
138EXPORT_SYMBOL(drm_pci_free); 159EXPORT_SYMBOL(drm_pci_free);
139 160
140/*@}*/ 161/*@}*/
diff --git a/drivers/char/drm/drm_pciids.h b/drivers/char/drm/drm_pciids.h
index 70ca4fa55c9d..58b1747cd440 100644
--- a/drivers/char/drm/drm_pciids.h
+++ b/drivers/char/drm/drm_pciids.h
@@ -25,6 +25,8 @@
25 {0x1002, 0x4965, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_R250}, \ 25 {0x1002, 0x4965, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_R250}, \
26 {0x1002, 0x4966, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_R250}, \ 26 {0x1002, 0x4966, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_R250}, \
27 {0x1002, 0x4967, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_R250}, \ 27 {0x1002, 0x4967, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_R250}, \
28 {0x1002, 0x4A49, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_R420}, \
29 {0x1002, 0x4A4B, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_R420}, \
28 {0x1002, 0x4C57, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV200|CHIP_IS_MOBILITY}, \ 30 {0x1002, 0x4C57, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV200|CHIP_IS_MOBILITY}, \
29 {0x1002, 0x4C58, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV200|CHIP_IS_MOBILITY}, \ 31 {0x1002, 0x4C58, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV200|CHIP_IS_MOBILITY}, \
30 {0x1002, 0x4C59, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV100|CHIP_IS_MOBILITY}, \ 32 {0x1002, 0x4C59, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV100|CHIP_IS_MOBILITY}, \
@@ -33,7 +35,17 @@
33 {0x1002, 0x4C65, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_R250|CHIP_IS_MOBILITY}, \ 35 {0x1002, 0x4C65, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_R250|CHIP_IS_MOBILITY}, \
34 {0x1002, 0x4C66, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_R250|CHIP_IS_MOBILITY}, \ 36 {0x1002, 0x4C66, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_R250|CHIP_IS_MOBILITY}, \
35 {0x1002, 0x4C67, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_R250|CHIP_IS_MOBILITY}, \ 37 {0x1002, 0x4C67, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_R250|CHIP_IS_MOBILITY}, \
38 {0x1002, 0x4E44, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_R300}, \
39 {0x1002, 0x4E45, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_R300}, \
40 {0x1002, 0x4E46, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV350}, \
41 {0x1002, 0x4E47, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_R300}, \
42 {0x1002, 0x4E48, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_R350}, \
43 {0x1002, 0x4E49, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_R350}, \
44 {0x1002, 0x4E4A, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV350}, \
45 {0x1002, 0x4E4B, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_R350}, \
36 {0x1002, 0x4E50, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV350|CHIP_IS_MOBILITY}, \ 46 {0x1002, 0x4E50, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV350|CHIP_IS_MOBILITY}, \
47 {0x1002, 0x4E51, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV350|CHIP_IS_MOBILITY}, \
48 {0x1002, 0x4E54, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV350|CHIP_IS_MOBILITY}, \
37 {0x1002, 0x5144, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_R100|CHIP_SINGLE_CRTC}, \ 49 {0x1002, 0x5144, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_R100|CHIP_SINGLE_CRTC}, \
38 {0x1002, 0x5145, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_R100|CHIP_SINGLE_CRTC}, \ 50 {0x1002, 0x5145, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_R100|CHIP_SINGLE_CRTC}, \
39 {0x1002, 0x5146, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_R100|CHIP_SINGLE_CRTC}, \ 51 {0x1002, 0x5146, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_R100|CHIP_SINGLE_CRTC}, \
@@ -56,6 +68,7 @@
56 {0x1002, 0x516A, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_R200}, \ 68 {0x1002, 0x516A, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_R200}, \
57 {0x1002, 0x516B, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_R200}, \ 69 {0x1002, 0x516B, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_R200}, \
58 {0x1002, 0x516C, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_R200}, \ 70 {0x1002, 0x516C, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_R200}, \
71 {0x1002, 0x5460, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV350}, \
59 {0x1002, 0x5834, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RS300|CHIP_IS_IGP}, \ 72 {0x1002, 0x5834, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RS300|CHIP_IS_IGP}, \
60 {0x1002, 0x5835, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RS300|CHIP_IS_IGP|CHIP_IS_MOBILITY}, \ 73 {0x1002, 0x5835, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RS300|CHIP_IS_IGP|CHIP_IS_MOBILITY}, \
61 {0x1002, 0x5836, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RS300|CHIP_IS_IGP}, \ 74 {0x1002, 0x5836, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RS300|CHIP_IS_IGP}, \
@@ -116,9 +129,10 @@
116 {0, 0, 0} 129 {0, 0, 0}
117 130
118#define mga_PCI_IDS \ 131#define mga_PCI_IDS \
119 {0x102b, 0x0521, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \ 132 {0x102b, 0x0520, PCI_ANY_ID, PCI_ANY_ID, 0, 0, MGA_CARD_TYPE_G200}, \
120 {0x102b, 0x0525, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \ 133 {0x102b, 0x0521, PCI_ANY_ID, PCI_ANY_ID, 0, 0, MGA_CARD_TYPE_G200}, \
121 {0x102b, 0x2527, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \ 134 {0x102b, 0x0525, PCI_ANY_ID, PCI_ANY_ID, 0, 0, MGA_CARD_TYPE_G400}, \
135 {0x102b, 0x2527, PCI_ANY_ID, PCI_ANY_ID, 0, 0, MGA_CARD_TYPE_G550}, \
122 {0, 0, 0} 136 {0, 0, 0}
123 137
124#define mach64_PCI_IDS \ 138#define mach64_PCI_IDS \
@@ -162,9 +176,10 @@
162 176
163#define viadrv_PCI_IDS \ 177#define viadrv_PCI_IDS \
164 {0x1106, 0x3022, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \ 178 {0x1106, 0x3022, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \
179 {0x1106, 0x3118, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \
165 {0x1106, 0x3122, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \ 180 {0x1106, 0x3122, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \
166 {0x1106, 0x7205, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \ 181 {0x1106, 0x7205, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \
167 {0x1106, 0x7204, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \ 182 {0x1106, 0x3108, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \
168 {0, 0, 0} 183 {0, 0, 0}
169 184
170#define i810_PCI_IDS \ 185#define i810_PCI_IDS \
@@ -181,33 +196,30 @@
181 {0x8086, 0x2572, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \ 196 {0x8086, 0x2572, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \
182 {0, 0, 0} 197 {0, 0, 0}
183 198
184#define gamma_PCI_IDS \
185 {0x3d3d, 0x0008, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \
186 {0, 0, 0}
187
188#define savage_PCI_IDS \ 199#define savage_PCI_IDS \
189 {0x5333, 0x8a22, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \ 200 {0x5333, 0x8a20, PCI_ANY_ID, PCI_ANY_ID, 0, 0, S3_SAVAGE3D}, \
190 {0x5333, 0x8a23, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \ 201 {0x5333, 0x8a21, PCI_ANY_ID, PCI_ANY_ID, 0, 0, S3_SAVAGE3D}, \
191 {0x5333, 0x8c10, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \ 202 {0x5333, 0x8a22, PCI_ANY_ID, PCI_ANY_ID, 0, 0, S3_SAVAGE4}, \
192 {0x5333, 0x8c11, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \ 203 {0x5333, 0x8a23, PCI_ANY_ID, PCI_ANY_ID, 0, 0, S3_SAVAGE4}, \
193 {0x5333, 0x8c12, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \ 204 {0x5333, 0x8c10, PCI_ANY_ID, PCI_ANY_ID, 0, 0, S3_SAVAGE_MX}, \
194 {0x5333, 0x8c13, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \ 205 {0x5333, 0x8c11, PCI_ANY_ID, PCI_ANY_ID, 0, 0, S3_SAVAGE_MX}, \
195 {0x5333, 0x8c20, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \ 206 {0x5333, 0x8c12, PCI_ANY_ID, PCI_ANY_ID, 0, 0, S3_SAVAGE_MX}, \
196 {0x5333, 0x8c21, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \ 207 {0x5333, 0x8c13, PCI_ANY_ID, PCI_ANY_ID, 0, 0, S3_SAVAGE_MX}, \
197 {0x5333, 0x8c22, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \ 208 {0x5333, 0x8c22, PCI_ANY_ID, PCI_ANY_ID, 0, 0, S3_SUPERSAVAGE}, \
198 {0x5333, 0x8c24, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \ 209 {0x5333, 0x8c24, PCI_ANY_ID, PCI_ANY_ID, 0, 0, S3_SUPERSAVAGE}, \
199 {0x5333, 0x8c26, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \ 210 {0x5333, 0x8c26, PCI_ANY_ID, PCI_ANY_ID, 0, 0, S3_SUPERSAVAGE}, \
200 {0x5333, 0x8c2a, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \ 211 {0x5333, 0x8c2a, PCI_ANY_ID, PCI_ANY_ID, 0, 0, S3_SUPERSAVAGE}, \
201 {0x5333, 0x8c2b, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \ 212 {0x5333, 0x8c2b, PCI_ANY_ID, PCI_ANY_ID, 0, 0, S3_SUPERSAVAGE}, \
202 {0x5333, 0x8c2c, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \ 213 {0x5333, 0x8c2c, PCI_ANY_ID, PCI_ANY_ID, 0, 0, S3_SUPERSAVAGE}, \
203 {0x5333, 0x8c2d, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \ 214 {0x5333, 0x8c2d, PCI_ANY_ID, PCI_ANY_ID, 0, 0, S3_SUPERSAVAGE}, \
204 {0x5333, 0x8c2e, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \ 215 {0x5333, 0x8c2e, PCI_ANY_ID, PCI_ANY_ID, 0, 0, S3_SUPERSAVAGE}, \
205 {0x5333, 0x8c2f, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \ 216 {0x5333, 0x8c2f, PCI_ANY_ID, PCI_ANY_ID, 0, 0, S3_SUPERSAVAGE}, \
206 {0x5333, 0x8a25, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \ 217 {0x5333, 0x8a25, PCI_ANY_ID, PCI_ANY_ID, 0, 0, S3_PROSAVAGE}, \
207 {0x5333, 0x8a26, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \ 218 {0x5333, 0x8a26, PCI_ANY_ID, PCI_ANY_ID, 0, 0, S3_PROSAVAGE}, \
208 {0x5333, 0x8d01, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \ 219 {0x5333, 0x8d01, PCI_ANY_ID, PCI_ANY_ID, 0, 0, S3_TWISTER}, \
209 {0x5333, 0x8d02, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \ 220 {0x5333, 0x8d02, PCI_ANY_ID, PCI_ANY_ID, 0, 0, S3_TWISTER}, \
210 {0x5333, 0x8d04, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \ 221 {0x5333, 0x8d03, PCI_ANY_ID, PCI_ANY_ID, 0, 0, S3_PROSAVAGEDDR}, \
222 {0x5333, 0x8d04, PCI_ANY_ID, PCI_ANY_ID, 0, 0, S3_PROSAVAGEDDR}, \
211 {0, 0, 0} 223 {0, 0, 0}
212 224
213#define ffb_PCI_IDS \ 225#define ffb_PCI_IDS \
@@ -223,10 +235,3 @@
223 {0x8086, 0x2772, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \ 235 {0x8086, 0x2772, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \
224 {0, 0, 0} 236 {0, 0, 0}
225 237
226#define viadrv_PCI_IDS \
227 {0x1106, 0x3022, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \
228 {0x1106, 0x3122, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \
229 {0x1106, 0x7205, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \
230 {0x1106, 0x7204, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \
231 {0, 0, 0}
232
diff --git a/drivers/char/drm/drm_proc.c b/drivers/char/drm/drm_proc.c
index 4774087d2e9e..32d2bb99462c 100644
--- a/drivers/char/drm/drm_proc.c
+++ b/drivers/char/drm/drm_proc.c
@@ -210,8 +210,8 @@ static int drm__vm_info(char *buf, char **start, off_t offset, int request,
210 210
211 /* Hardcoded from _DRM_FRAME_BUFFER, 211 /* Hardcoded from _DRM_FRAME_BUFFER,
212 _DRM_REGISTERS, _DRM_SHM, _DRM_AGP, and 212 _DRM_REGISTERS, _DRM_SHM, _DRM_AGP, and
213 _DRM_SCATTER_GATHER. */ 213 _DRM_SCATTER_GATHER and _DRM_CONSISTENT */
214 const char *types[] = { "FB", "REG", "SHM", "AGP", "SG" }; 214 const char *types[] = { "FB", "REG", "SHM", "AGP", "SG", "PCI" };
215 const char *type; 215 const char *type;
216 int i; 216 int i;
217 217
@@ -229,16 +229,19 @@ static int drm__vm_info(char *buf, char **start, off_t offset, int request,
229 if (dev->maplist != NULL) list_for_each(list, &dev->maplist->head) { 229 if (dev->maplist != NULL) list_for_each(list, &dev->maplist->head) {
230 r_list = list_entry(list, drm_map_list_t, head); 230 r_list = list_entry(list, drm_map_list_t, head);
231 map = r_list->map; 231 map = r_list->map;
232 if(!map) continue; 232 if(!map)
233 if (map->type < 0 || map->type > 4) type = "??"; 233 continue;
234 else type = types[map->type]; 234 if (map->type < 0 || map->type > 5)
235 DRM_PROC_PRINT("%4d 0x%08lx 0x%08lx %4.4s 0x%02x 0x%08lx ", 235 type = "??";
236 else
237 type = types[map->type];
238 DRM_PROC_PRINT("%4d 0x%08lx 0x%08lx %4.4s 0x%02x 0x%08x ",
236 i, 239 i,
237 map->offset, 240 map->offset,
238 map->size, 241 map->size,
239 type, 242 type,
240 map->flags, 243 map->flags,
241 (unsigned long)map->handle); 244 r_list->user_token);
242 if (map->mtrr < 0) { 245 if (map->mtrr < 0) {
243 DRM_PROC_PRINT("none\n"); 246 DRM_PROC_PRINT("none\n");
244 } else { 247 } else {
diff --git a/drivers/char/drm/drm_scatter.c b/drivers/char/drm/drm_scatter.c
index 54fddb6ea2d1..ed267d49bc6a 100644
--- a/drivers/char/drm/drm_scatter.c
+++ b/drivers/char/drm/drm_scatter.c
@@ -61,6 +61,12 @@ void drm_sg_cleanup( drm_sg_mem_t *entry )
61 DRM_MEM_SGLISTS ); 61 DRM_MEM_SGLISTS );
62} 62}
63 63
64#ifdef _LP64
65# define ScatterHandle(x) (unsigned int)((x >> 32) + (x & ((1L << 32) - 1)))
66#else
67# define ScatterHandle(x) (unsigned int)(x)
68#endif
69
64int drm_sg_alloc( struct inode *inode, struct file *filp, 70int drm_sg_alloc( struct inode *inode, struct file *filp,
65 unsigned int cmd, unsigned long arg ) 71 unsigned int cmd, unsigned long arg )
66{ 72{
@@ -133,12 +139,13 @@ int drm_sg_alloc( struct inode *inode, struct file *filp,
133 */ 139 */
134 memset( entry->virtual, 0, pages << PAGE_SHIFT ); 140 memset( entry->virtual, 0, pages << PAGE_SHIFT );
135 141
136 entry->handle = (unsigned long)entry->virtual; 142 entry->handle = ScatterHandle((unsigned long)entry->virtual);
137 143
138 DRM_DEBUG( "sg alloc handle = %08lx\n", entry->handle ); 144 DRM_DEBUG( "sg alloc handle = %08lx\n", entry->handle );
139 DRM_DEBUG( "sg alloc virtual = %p\n", entry->virtual ); 145 DRM_DEBUG( "sg alloc virtual = %p\n", entry->virtual );
140 146
141 for ( i = entry->handle, j = 0 ; j < pages ; i += PAGE_SIZE, j++ ) { 147 for (i = (unsigned long)entry->virtual, j = 0; j < pages;
148 i += PAGE_SIZE, j++) {
142 entry->pagelist[j] = vmalloc_to_page((void *)i); 149 entry->pagelist[j] = vmalloc_to_page((void *)i);
143 if (!entry->pagelist[j]) 150 if (!entry->pagelist[j])
144 goto failed; 151 goto failed;
diff --git a/drivers/char/drm/drm_stub.c b/drivers/char/drm/drm_stub.c
index 48829a1a086a..95a976c96eb8 100644
--- a/drivers/char/drm/drm_stub.c
+++ b/drivers/char/drm/drm_stub.c
@@ -75,6 +75,11 @@ static int drm_fill_in_dev(drm_device_t *dev, struct pci_dev *pdev, const struct
75 dev->pci_func = PCI_FUNC(pdev->devfn); 75 dev->pci_func = PCI_FUNC(pdev->devfn);
76 dev->irq = pdev->irq; 76 dev->irq = pdev->irq;
77 77
78 dev->maplist = drm_calloc(1, sizeof(*dev->maplist), DRM_MEM_MAPS);
79 if (dev->maplist == NULL)
80 return -ENOMEM;
81 INIT_LIST_HEAD(&dev->maplist->head);
82
78 /* the DRM has 6 basic counters */ 83 /* the DRM has 6 basic counters */
79 dev->counters = 6; 84 dev->counters = 6;
80 dev->types[0] = _DRM_STAT_LOCK; 85 dev->types[0] = _DRM_STAT_LOCK;
@@ -91,7 +96,8 @@ static int drm_fill_in_dev(drm_device_t *dev, struct pci_dev *pdev, const struct
91 goto error_out_unreg; 96 goto error_out_unreg;
92 97
93 if (drm_core_has_AGP(dev)) { 98 if (drm_core_has_AGP(dev)) {
94 dev->agp = drm_agp_init(dev); 99 if (drm_device_is_agp(dev))
100 dev->agp = drm_agp_init(dev);
95 if (drm_core_check_feature(dev, DRIVER_REQUIRE_AGP) && (dev->agp == NULL)) { 101 if (drm_core_check_feature(dev, DRIVER_REQUIRE_AGP) && (dev->agp == NULL)) {
96 DRM_ERROR( "Cannot initialize the agpgart module.\n" ); 102 DRM_ERROR( "Cannot initialize the agpgart module.\n" );
97 retcode = -EINVAL; 103 retcode = -EINVAL;
diff --git a/drivers/char/drm/drm_vm.c b/drivers/char/drm/drm_vm.c
index 621220f3f372..ced4215e2275 100644
--- a/drivers/char/drm/drm_vm.c
+++ b/drivers/char/drm/drm_vm.c
@@ -73,12 +73,13 @@ static __inline__ struct page *drm_do_vm_nopage(struct vm_area_struct *vma,
73 r_list = list_entry(list, drm_map_list_t, head); 73 r_list = list_entry(list, drm_map_list_t, head);
74 map = r_list->map; 74 map = r_list->map;
75 if (!map) continue; 75 if (!map) continue;
76 if (map->offset == VM_OFFSET(vma)) break; 76 if (r_list->user_token == VM_OFFSET(vma))
77 break;
77 } 78 }
78 79
79 if (map && map->type == _DRM_AGP) { 80 if (map && map->type == _DRM_AGP) {
80 unsigned long offset = address - vma->vm_start; 81 unsigned long offset = address - vma->vm_start;
81 unsigned long baddr = VM_OFFSET(vma) + offset; 82 unsigned long baddr = map->offset + offset;
82 struct drm_agp_mem *agpmem; 83 struct drm_agp_mem *agpmem;
83 struct page *page; 84 struct page *page;
84 85
@@ -210,6 +211,8 @@ static void drm_vm_shm_close(struct vm_area_struct *vma)
210 } 211 }
211 212
212 if(!found_maps) { 213 if(!found_maps) {
214 drm_dma_handle_t dmah;
215
213 switch (map->type) { 216 switch (map->type) {
214 case _DRM_REGISTERS: 217 case _DRM_REGISTERS:
215 case _DRM_FRAME_BUFFER: 218 case _DRM_FRAME_BUFFER:
@@ -228,6 +231,12 @@ static void drm_vm_shm_close(struct vm_area_struct *vma)
228 case _DRM_AGP: 231 case _DRM_AGP:
229 case _DRM_SCATTER_GATHER: 232 case _DRM_SCATTER_GATHER:
230 break; 233 break;
234 case _DRM_CONSISTENT:
235 dmah.vaddr = map->handle;
236 dmah.busaddr = map->offset;
237 dmah.size = map->size;
238 __drm_pci_free(dev, &dmah);
239 break;
231 } 240 }
232 drm_free(map, sizeof(*map), DRM_MEM_MAPS); 241 drm_free(map, sizeof(*map), DRM_MEM_MAPS);
233 } 242 }
@@ -296,7 +305,7 @@ static __inline__ struct page *drm_do_vm_sg_nopage(struct vm_area_struct *vma,
296 305
297 306
298 offset = address - vma->vm_start; 307 offset = address - vma->vm_start;
299 map_offset = map->offset - dev->sg->handle; 308 map_offset = map->offset - (unsigned long)dev->sg->virtual;
300 page_offset = (offset >> PAGE_SHIFT) + (map_offset >> PAGE_SHIFT); 309 page_offset = (offset >> PAGE_SHIFT) + (map_offset >> PAGE_SHIFT);
301 page = entry->pagelist[page_offset]; 310 page = entry->pagelist[page_offset];
302 get_page(page); 311 get_page(page);
@@ -305,8 +314,6 @@ static __inline__ struct page *drm_do_vm_sg_nopage(struct vm_area_struct *vma,
305} 314}
306 315
307 316
308#if LINUX_VERSION_CODE > KERNEL_VERSION(2,6,0)
309
310static struct page *drm_vm_nopage(struct vm_area_struct *vma, 317static struct page *drm_vm_nopage(struct vm_area_struct *vma,
311 unsigned long address, 318 unsigned long address,
312 int *type) { 319 int *type) {
@@ -335,35 +342,6 @@ static struct page *drm_vm_sg_nopage(struct vm_area_struct *vma,
335 return drm_do_vm_sg_nopage(vma, address); 342 return drm_do_vm_sg_nopage(vma, address);
336} 343}
337 344
338#else /* LINUX_VERSION_CODE <= KERNEL_VERSION(2,6,0) */
339
340static struct page *drm_vm_nopage(struct vm_area_struct *vma,
341 unsigned long address,
342 int unused) {
343 return drm_do_vm_nopage(vma, address);
344}
345
346static struct page *drm_vm_shm_nopage(struct vm_area_struct *vma,
347 unsigned long address,
348 int unused) {
349 return drm_do_vm_shm_nopage(vma, address);
350}
351
352static struct page *drm_vm_dma_nopage(struct vm_area_struct *vma,
353 unsigned long address,
354 int unused) {
355 return drm_do_vm_dma_nopage(vma, address);
356}
357
358static struct page *drm_vm_sg_nopage(struct vm_area_struct *vma,
359 unsigned long address,
360 int unused) {
361 return drm_do_vm_sg_nopage(vma, address);
362}
363
364#endif
365
366
367/** AGP virtual memory operations */ 345/** AGP virtual memory operations */
368static struct vm_operations_struct drm_vm_ops = { 346static struct vm_operations_struct drm_vm_ops = {
369 .nopage = drm_vm_nopage, 347 .nopage = drm_vm_nopage,
@@ -487,11 +465,7 @@ static int drm_mmap_dma(struct file *filp, struct vm_area_struct *vma)
487 465
488 vma->vm_ops = &drm_vm_dma_ops; 466 vma->vm_ops = &drm_vm_dma_ops;
489 467
490#if LINUX_VERSION_CODE <= 0x02040e /* KERNEL_VERSION(2,4,14) */
491 vma->vm_flags |= VM_LOCKED | VM_SHM; /* Don't swap */
492#else
493 vma->vm_flags |= VM_RESERVED; /* Don't swap */ 468 vma->vm_flags |= VM_RESERVED; /* Don't swap */
494#endif
495 469
496 vma->vm_file = filp; /* Needed for drm_vm_open() */ 470 vma->vm_file = filp; /* Needed for drm_vm_open() */
497 drm_vm_open(vma); 471 drm_vm_open(vma);
@@ -560,13 +534,12 @@ int drm_mmap(struct file *filp, struct vm_area_struct *vma)
560 for performance, even if the list was a 534 for performance, even if the list was a
561 bit longer. */ 535 bit longer. */
562 list_for_each(list, &dev->maplist->head) { 536 list_for_each(list, &dev->maplist->head) {
563 unsigned long off;
564 537
565 r_list = list_entry(list, drm_map_list_t, head); 538 r_list = list_entry(list, drm_map_list_t, head);
566 map = r_list->map; 539 map = r_list->map;
567 if (!map) continue; 540 if (!map) continue;
568 off = dev->driver->get_map_ofs(map); 541 if (r_list->user_token == VM_OFFSET(vma))
569 if (off == VM_OFFSET(vma)) break; 542 break;
570 } 543 }
571 544
572 if (!map || ((map->flags&_DRM_RESTRICTED) && !capable(CAP_SYS_ADMIN))) 545 if (!map || ((map->flags&_DRM_RESTRICTED) && !capable(CAP_SYS_ADMIN)))
@@ -605,17 +578,17 @@ int drm_mmap(struct file *filp, struct vm_area_struct *vma)
605 /* fall through to _DRM_FRAME_BUFFER... */ 578 /* fall through to _DRM_FRAME_BUFFER... */
606 case _DRM_FRAME_BUFFER: 579 case _DRM_FRAME_BUFFER:
607 case _DRM_REGISTERS: 580 case _DRM_REGISTERS:
608 if (VM_OFFSET(vma) >= __pa(high_memory)) {
609#if defined(__i386__) || defined(__x86_64__) 581#if defined(__i386__) || defined(__x86_64__)
610 if (boot_cpu_data.x86 > 3 && map->type != _DRM_AGP) { 582 if (boot_cpu_data.x86 > 3 && map->type != _DRM_AGP) {
611 pgprot_val(vma->vm_page_prot) |= _PAGE_PCD; 583 pgprot_val(vma->vm_page_prot) |= _PAGE_PCD;
612 pgprot_val(vma->vm_page_prot) &= ~_PAGE_PWT; 584 pgprot_val(vma->vm_page_prot) &= ~_PAGE_PWT;
613 } 585 }
614#elif defined(__powerpc__) 586#elif defined(__powerpc__)
615 pgprot_val(vma->vm_page_prot) |= _PAGE_NO_CACHE | _PAGE_GUARDED; 587 pgprot_val(vma->vm_page_prot) |= _PAGE_NO_CACHE;
588 if (map->type == _DRM_REGISTERS)
589 pgprot_val(vma->vm_page_prot) |= _PAGE_GUARDED;
616#endif 590#endif
617 vma->vm_flags |= VM_IO; /* not in core dump */ 591 vma->vm_flags |= VM_IO; /* not in core dump */
618 }
619#if defined(__ia64__) 592#if defined(__ia64__)
620 if (efi_range_is_wc(vma->vm_start, vma->vm_end - 593 if (efi_range_is_wc(vma->vm_start, vma->vm_end -
621 vma->vm_start)) 594 vma->vm_start))
@@ -628,12 +601,12 @@ int drm_mmap(struct file *filp, struct vm_area_struct *vma)
628 offset = dev->driver->get_reg_ofs(dev); 601 offset = dev->driver->get_reg_ofs(dev);
629#ifdef __sparc__ 602#ifdef __sparc__
630 if (io_remap_pfn_range(DRM_RPR_ARG(vma) vma->vm_start, 603 if (io_remap_pfn_range(DRM_RPR_ARG(vma) vma->vm_start,
631 (VM_OFFSET(vma) + offset) >> PAGE_SHIFT, 604 (map->offset + offset) >> PAGE_SHIFT,
632 vma->vm_end - vma->vm_start, 605 vma->vm_end - vma->vm_start,
633 vma->vm_page_prot)) 606 vma->vm_page_prot))
634#else 607#else
635 if (io_remap_pfn_range(vma, vma->vm_start, 608 if (io_remap_pfn_range(vma, vma->vm_start,
636 (VM_OFFSET(vma) + offset) >> PAGE_SHIFT, 609 (map->offset + offset) >> PAGE_SHIFT,
637 vma->vm_end - vma->vm_start, 610 vma->vm_end - vma->vm_start,
638 vma->vm_page_prot)) 611 vma->vm_page_prot))
639#endif 612#endif
@@ -641,37 +614,28 @@ int drm_mmap(struct file *filp, struct vm_area_struct *vma)
641 DRM_DEBUG(" Type = %d; start = 0x%lx, end = 0x%lx," 614 DRM_DEBUG(" Type = %d; start = 0x%lx, end = 0x%lx,"
642 " offset = 0x%lx\n", 615 " offset = 0x%lx\n",
643 map->type, 616 map->type,
644 vma->vm_start, vma->vm_end, VM_OFFSET(vma) + offset); 617 vma->vm_start, vma->vm_end, map->offset + offset);
645 vma->vm_ops = &drm_vm_ops; 618 vma->vm_ops = &drm_vm_ops;
646 break; 619 break;
647 case _DRM_SHM: 620 case _DRM_SHM:
621 case _DRM_CONSISTENT:
622 /* Consistent memory is really like shared memory. It's only
623 * allocate in a different way */
648 vma->vm_ops = &drm_vm_shm_ops; 624 vma->vm_ops = &drm_vm_shm_ops;
649 vma->vm_private_data = (void *)map; 625 vma->vm_private_data = (void *)map;
650 /* Don't let this area swap. Change when 626 /* Don't let this area swap. Change when
651 DRM_KERNEL advisory is supported. */ 627 DRM_KERNEL advisory is supported. */
652#if LINUX_VERSION_CODE <= 0x02040e /* KERNEL_VERSION(2,4,14) */
653 vma->vm_flags |= VM_LOCKED;
654#else
655 vma->vm_flags |= VM_RESERVED; 628 vma->vm_flags |= VM_RESERVED;
656#endif
657 break; 629 break;
658 case _DRM_SCATTER_GATHER: 630 case _DRM_SCATTER_GATHER:
659 vma->vm_ops = &drm_vm_sg_ops; 631 vma->vm_ops = &drm_vm_sg_ops;
660 vma->vm_private_data = (void *)map; 632 vma->vm_private_data = (void *)map;
661#if LINUX_VERSION_CODE <= 0x02040e /* KERNEL_VERSION(2,4,14) */
662 vma->vm_flags |= VM_LOCKED;
663#else
664 vma->vm_flags |= VM_RESERVED; 633 vma->vm_flags |= VM_RESERVED;
665#endif
666 break; 634 break;
667 default: 635 default:
668 return -EINVAL; /* This should never happen. */ 636 return -EINVAL; /* This should never happen. */
669 } 637 }
670#if LINUX_VERSION_CODE <= 0x02040e /* KERNEL_VERSION(2,4,14) */
671 vma->vm_flags |= VM_LOCKED | VM_SHM; /* Don't swap */
672#else
673 vma->vm_flags |= VM_RESERVED; /* Don't swap */ 638 vma->vm_flags |= VM_RESERVED; /* Don't swap */
674#endif
675 639
676 vma->vm_file = filp; /* Needed for drm_vm_open() */ 640 vma->vm_file = filp; /* Needed for drm_vm_open() */
677 drm_vm_open(vma); 641 drm_vm_open(vma);
diff --git a/drivers/char/drm/ffb_drv.c b/drivers/char/drm/ffb_drv.c
index ec614fff8f04..1bd0d55ee0f0 100644
--- a/drivers/char/drm/ffb_drv.c
+++ b/drivers/char/drm/ffb_drv.c
@@ -152,14 +152,11 @@ static drm_map_t *ffb_find_map(struct file *filp, unsigned long off)
152 return NULL; 152 return NULL;
153 153
154 list_for_each(list, &dev->maplist->head) { 154 list_for_each(list, &dev->maplist->head) {
155 unsigned long uoff;
156
157 r_list = (drm_map_list_t *)list; 155 r_list = (drm_map_list_t *)list;
158 map = r_list->map; 156 map = r_list->map;
159 if (!map) 157 if (!map)
160 continue; 158 continue;
161 uoff = (map->offset & 0xffffffff); 159 if (r_list->user_token == off)
162 if (uoff == off)
163 return map; 160 return map;
164 } 161 }
165 162
diff --git a/drivers/char/drm/gamma_context.h b/drivers/char/drm/gamma_context.h
deleted file mode 100644
index d11b507f87ee..000000000000
--- a/drivers/char/drm/gamma_context.h
+++ /dev/null
@@ -1,492 +0,0 @@
1/* drm_context.h -- IOCTLs for generic contexts -*- linux-c -*-
2 * Created: Fri Nov 24 18:31:37 2000 by gareth@valinux.com
3 *
4 * Copyright 1999, 2000 Precision Insight, Inc., Cedar Park, Texas.
5 * Copyright 2000 VA Linux Systems, Inc., Sunnyvale, California.
6 * All Rights Reserved.
7 *
8 * Permission is hereby granted, free of charge, to any person obtaining a
9 * copy of this software and associated documentation files (the "Software"),
10 * to deal in the Software without restriction, including without limitation
11 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
12 * and/or sell copies of the Software, and to permit persons to whom the
13 * Software is furnished to do so, subject to the following conditions:
14 *
15 * The above copyright notice and this permission notice (including the next
16 * paragraph) shall be included in all copies or substantial portions of the
17 * Software.
18 *
19 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
20 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
21 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
22 * VA LINUX SYSTEMS AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
23 * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
24 * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
25 * OTHER DEALINGS IN THE SOFTWARE.
26 *
27 * Authors:
28 * Rickard E. (Rik) Faith <faith@valinux.com>
29 * Gareth Hughes <gareth@valinux.com>
30 * ChangeLog:
31 * 2001-11-16 Torsten Duwe <duwe@caldera.de>
32 * added context constructor/destructor hooks,
33 * needed by SiS driver's memory management.
34 */
35
36/* ================================================================
37 * Old-style context support -- only used by gamma.
38 */
39
40
41/* The drm_read and drm_write_string code (especially that which manages
42 the circular buffer), is based on Alessandro Rubini's LINUX DEVICE
43 DRIVERS (Cambridge: O'Reilly, 1998), pages 111-113. */
44
45ssize_t gamma_fops_read(struct file *filp, char __user *buf, size_t count, loff_t *off)
46{
47 drm_file_t *priv = filp->private_data;
48 drm_device_t *dev = priv->dev;
49 int left;
50 int avail;
51 int send;
52 int cur;
53
54 DRM_DEBUG("%p, %p\n", dev->buf_rp, dev->buf_wp);
55
56 while (dev->buf_rp == dev->buf_wp) {
57 DRM_DEBUG(" sleeping\n");
58 if (filp->f_flags & O_NONBLOCK) {
59 return -EAGAIN;
60 }
61 interruptible_sleep_on(&dev->buf_readers);
62 if (signal_pending(current)) {
63 DRM_DEBUG(" interrupted\n");
64 return -ERESTARTSYS;
65 }
66 DRM_DEBUG(" awake\n");
67 }
68
69 left = (dev->buf_rp + DRM_BSZ - dev->buf_wp) % DRM_BSZ;
70 avail = DRM_BSZ - left;
71 send = DRM_MIN(avail, count);
72
73 while (send) {
74 if (dev->buf_wp > dev->buf_rp) {
75 cur = DRM_MIN(send, dev->buf_wp - dev->buf_rp);
76 } else {
77 cur = DRM_MIN(send, dev->buf_end - dev->buf_rp);
78 }
79 if (copy_to_user(buf, dev->buf_rp, cur))
80 return -EFAULT;
81 dev->buf_rp += cur;
82 if (dev->buf_rp == dev->buf_end) dev->buf_rp = dev->buf;
83 send -= cur;
84 }
85
86 wake_up_interruptible(&dev->buf_writers);
87 return DRM_MIN(avail, count);
88}
89
90
91/* In an incredibly convoluted setup, the kernel module actually calls
92 * back into the X server to perform context switches on behalf of the
93 * 3d clients.
94 */
95int DRM(write_string)(drm_device_t *dev, const char *s)
96{
97 int left = (dev->buf_rp + DRM_BSZ - dev->buf_wp) % DRM_BSZ;
98 int send = strlen(s);
99 int count;
100
101 DRM_DEBUG("%d left, %d to send (%p, %p)\n",
102 left, send, dev->buf_rp, dev->buf_wp);
103
104 if (left == 1 || dev->buf_wp != dev->buf_rp) {
105 DRM_ERROR("Buffer not empty (%d left, wp = %p, rp = %p)\n",
106 left,
107 dev->buf_wp,
108 dev->buf_rp);
109 }
110
111 while (send) {
112 if (dev->buf_wp >= dev->buf_rp) {
113 count = DRM_MIN(send, dev->buf_end - dev->buf_wp);
114 if (count == left) --count; /* Leave a hole */
115 } else {
116 count = DRM_MIN(send, dev->buf_rp - dev->buf_wp - 1);
117 }
118 strncpy(dev->buf_wp, s, count);
119 dev->buf_wp += count;
120 if (dev->buf_wp == dev->buf_end) dev->buf_wp = dev->buf;
121 send -= count;
122 }
123
124 if (dev->buf_async) kill_fasync(&dev->buf_async, SIGIO, POLL_IN);
125
126 DRM_DEBUG("waking\n");
127 wake_up_interruptible(&dev->buf_readers);
128 return 0;
129}
130
131unsigned int gamma_fops_poll(struct file *filp, struct poll_table_struct *wait)
132{
133 drm_file_t *priv = filp->private_data;
134 drm_device_t *dev = priv->dev;
135
136 poll_wait(filp, &dev->buf_readers, wait);
137 if (dev->buf_wp != dev->buf_rp) return POLLIN | POLLRDNORM;
138 return 0;
139}
140
141int DRM(context_switch)(drm_device_t *dev, int old, int new)
142{
143 char buf[64];
144 drm_queue_t *q;
145
146 if (test_and_set_bit(0, &dev->context_flag)) {
147 DRM_ERROR("Reentering -- FIXME\n");
148 return -EBUSY;
149 }
150
151 DRM_DEBUG("Context switch from %d to %d\n", old, new);
152
153 if (new >= dev->queue_count) {
154 clear_bit(0, &dev->context_flag);
155 return -EINVAL;
156 }
157
158 if (new == dev->last_context) {
159 clear_bit(0, &dev->context_flag);
160 return 0;
161 }
162
163 q = dev->queuelist[new];
164 atomic_inc(&q->use_count);
165 if (atomic_read(&q->use_count) == 1) {
166 atomic_dec(&q->use_count);
167 clear_bit(0, &dev->context_flag);
168 return -EINVAL;
169 }
170
171 /* This causes the X server to wake up & do a bunch of hardware
172 * interaction to actually effect the context switch.
173 */
174 sprintf(buf, "C %d %d\n", old, new);
175 DRM(write_string)(dev, buf);
176
177 atomic_dec(&q->use_count);
178
179 return 0;
180}
181
182int DRM(context_switch_complete)(drm_device_t *dev, int new)
183{
184 drm_device_dma_t *dma = dev->dma;
185
186 dev->last_context = new; /* PRE/POST: This is the _only_ writer. */
187 dev->last_switch = jiffies;
188
189 if (!_DRM_LOCK_IS_HELD(dev->lock.hw_lock->lock)) {
190 DRM_ERROR("Lock isn't held after context switch\n");
191 }
192
193 if (!dma || !(dma->next_buffer && dma->next_buffer->while_locked)) {
194 if (DRM(lock_free)(dev, &dev->lock.hw_lock->lock,
195 DRM_KERNEL_CONTEXT)) {
196 DRM_ERROR("Cannot free lock\n");
197 }
198 }
199
200 clear_bit(0, &dev->context_flag);
201 wake_up_interruptible(&dev->context_wait);
202
203 return 0;
204}
205
206static int DRM(init_queue)(drm_device_t *dev, drm_queue_t *q, drm_ctx_t *ctx)
207{
208 DRM_DEBUG("\n");
209
210 if (atomic_read(&q->use_count) != 1
211 || atomic_read(&q->finalization)
212 || atomic_read(&q->block_count)) {
213 DRM_ERROR("New queue is already in use: u%d f%d b%d\n",
214 atomic_read(&q->use_count),
215 atomic_read(&q->finalization),
216 atomic_read(&q->block_count));
217 }
218
219 atomic_set(&q->finalization, 0);
220 atomic_set(&q->block_count, 0);
221 atomic_set(&q->block_read, 0);
222 atomic_set(&q->block_write, 0);
223 atomic_set(&q->total_queued, 0);
224 atomic_set(&q->total_flushed, 0);
225 atomic_set(&q->total_locks, 0);
226
227 init_waitqueue_head(&q->write_queue);
228 init_waitqueue_head(&q->read_queue);
229 init_waitqueue_head(&q->flush_queue);
230
231 q->flags = ctx->flags;
232
233 DRM(waitlist_create)(&q->waitlist, dev->dma->buf_count);
234
235 return 0;
236}
237
238
239/* drm_alloc_queue:
240PRE: 1) dev->queuelist[0..dev->queue_count] is allocated and will not
241 disappear (so all deallocation must be done after IOCTLs are off)
242 2) dev->queue_count < dev->queue_slots
243 3) dev->queuelist[i].use_count == 0 and
244 dev->queuelist[i].finalization == 0 if i not in use
245POST: 1) dev->queuelist[i].use_count == 1
246 2) dev->queue_count < dev->queue_slots */
247
248static int DRM(alloc_queue)(drm_device_t *dev)
249{
250 int i;
251 drm_queue_t *queue;
252 int oldslots;
253 int newslots;
254 /* Check for a free queue */
255 for (i = 0; i < dev->queue_count; i++) {
256 atomic_inc(&dev->queuelist[i]->use_count);
257 if (atomic_read(&dev->queuelist[i]->use_count) == 1
258 && !atomic_read(&dev->queuelist[i]->finalization)) {
259 DRM_DEBUG("%d (free)\n", i);
260 return i;
261 }
262 atomic_dec(&dev->queuelist[i]->use_count);
263 }
264 /* Allocate a new queue */
265 down(&dev->struct_sem);
266
267 queue = DRM(alloc)(sizeof(*queue), DRM_MEM_QUEUES);
268 memset(queue, 0, sizeof(*queue));
269 atomic_set(&queue->use_count, 1);
270
271 ++dev->queue_count;
272 if (dev->queue_count >= dev->queue_slots) {
273 oldslots = dev->queue_slots * sizeof(*dev->queuelist);
274 if (!dev->queue_slots) dev->queue_slots = 1;
275 dev->queue_slots *= 2;
276 newslots = dev->queue_slots * sizeof(*dev->queuelist);
277
278 dev->queuelist = DRM(realloc)(dev->queuelist,
279 oldslots,
280 newslots,
281 DRM_MEM_QUEUES);
282 if (!dev->queuelist) {
283 up(&dev->struct_sem);
284 DRM_DEBUG("out of memory\n");
285 return -ENOMEM;
286 }
287 }
288 dev->queuelist[dev->queue_count-1] = queue;
289
290 up(&dev->struct_sem);
291 DRM_DEBUG("%d (new)\n", dev->queue_count - 1);
292 return dev->queue_count - 1;
293}
294
295int DRM(resctx)(struct inode *inode, struct file *filp,
296 unsigned int cmd, unsigned long arg)
297{
298 drm_ctx_res_t __user *argp = (void __user *)arg;
299 drm_ctx_res_t res;
300 drm_ctx_t ctx;
301 int i;
302
303 DRM_DEBUG("%d\n", DRM_RESERVED_CONTEXTS);
304 if (copy_from_user(&res, argp, sizeof(res)))
305 return -EFAULT;
306 if (res.count >= DRM_RESERVED_CONTEXTS) {
307 memset(&ctx, 0, sizeof(ctx));
308 for (i = 0; i < DRM_RESERVED_CONTEXTS; i++) {
309 ctx.handle = i;
310 if (copy_to_user(&res.contexts[i],
311 &i,
312 sizeof(i)))
313 return -EFAULT;
314 }
315 }
316 res.count = DRM_RESERVED_CONTEXTS;
317 if (copy_to_user(argp, &res, sizeof(res)))
318 return -EFAULT;
319 return 0;
320}
321
322int DRM(addctx)(struct inode *inode, struct file *filp,
323 unsigned int cmd, unsigned long arg)
324{
325 drm_file_t *priv = filp->private_data;
326 drm_device_t *dev = priv->dev;
327 drm_ctx_t ctx;
328 drm_ctx_t __user *argp = (void __user *)arg;
329
330 if (copy_from_user(&ctx, argp, sizeof(ctx)))
331 return -EFAULT;
332 if ((ctx.handle = DRM(alloc_queue)(dev)) == DRM_KERNEL_CONTEXT) {
333 /* Init kernel's context and get a new one. */
334 DRM(init_queue)(dev, dev->queuelist[ctx.handle], &ctx);
335 ctx.handle = DRM(alloc_queue)(dev);
336 }
337 DRM(init_queue)(dev, dev->queuelist[ctx.handle], &ctx);
338 DRM_DEBUG("%d\n", ctx.handle);
339 if (copy_to_user(argp, &ctx, sizeof(ctx)))
340 return -EFAULT;
341 return 0;
342}
343
344int DRM(modctx)(struct inode *inode, struct file *filp,
345 unsigned int cmd, unsigned long arg)
346{
347 drm_file_t *priv = filp->private_data;
348 drm_device_t *dev = priv->dev;
349 drm_ctx_t ctx;
350 drm_queue_t *q;
351
352 if (copy_from_user(&ctx, (drm_ctx_t __user *)arg, sizeof(ctx)))
353 return -EFAULT;
354
355 DRM_DEBUG("%d\n", ctx.handle);
356
357 if (ctx.handle < 0 || ctx.handle >= dev->queue_count) return -EINVAL;
358 q = dev->queuelist[ctx.handle];
359
360 atomic_inc(&q->use_count);
361 if (atomic_read(&q->use_count) == 1) {
362 /* No longer in use */
363 atomic_dec(&q->use_count);
364 return -EINVAL;
365 }
366
367 if (DRM_BUFCOUNT(&q->waitlist)) {
368 atomic_dec(&q->use_count);
369 return -EBUSY;
370 }
371
372 q->flags = ctx.flags;
373
374 atomic_dec(&q->use_count);
375 return 0;
376}
377
378int DRM(getctx)(struct inode *inode, struct file *filp,
379 unsigned int cmd, unsigned long arg)
380{
381 drm_file_t *priv = filp->private_data;
382 drm_device_t *dev = priv->dev;
383 drm_ctx_t __user *argp = (void __user *)arg;
384 drm_ctx_t ctx;
385 drm_queue_t *q;
386
387 if (copy_from_user(&ctx, argp, sizeof(ctx)))
388 return -EFAULT;
389
390 DRM_DEBUG("%d\n", ctx.handle);
391
392 if (ctx.handle >= dev->queue_count) return -EINVAL;
393 q = dev->queuelist[ctx.handle];
394
395 atomic_inc(&q->use_count);
396 if (atomic_read(&q->use_count) == 1) {
397 /* No longer in use */
398 atomic_dec(&q->use_count);
399 return -EINVAL;
400 }
401
402 ctx.flags = q->flags;
403 atomic_dec(&q->use_count);
404
405 if (copy_to_user(argp, &ctx, sizeof(ctx)))
406 return -EFAULT;
407
408 return 0;
409}
410
411int DRM(switchctx)(struct inode *inode, struct file *filp,
412 unsigned int cmd, unsigned long arg)
413{
414 drm_file_t *priv = filp->private_data;
415 drm_device_t *dev = priv->dev;
416 drm_ctx_t ctx;
417
418 if (copy_from_user(&ctx, (drm_ctx_t __user *)arg, sizeof(ctx)))
419 return -EFAULT;
420 DRM_DEBUG("%d\n", ctx.handle);
421 return DRM(context_switch)(dev, dev->last_context, ctx.handle);
422}
423
424int DRM(newctx)(struct inode *inode, struct file *filp,
425 unsigned int cmd, unsigned long arg)
426{
427 drm_file_t *priv = filp->private_data;
428 drm_device_t *dev = priv->dev;
429 drm_ctx_t ctx;
430
431 if (copy_from_user(&ctx, (drm_ctx_t __user *)arg, sizeof(ctx)))
432 return -EFAULT;
433 DRM_DEBUG("%d\n", ctx.handle);
434 DRM(context_switch_complete)(dev, ctx.handle);
435
436 return 0;
437}
438
439int DRM(rmctx)(struct inode *inode, struct file *filp,
440 unsigned int cmd, unsigned long arg)
441{
442 drm_file_t *priv = filp->private_data;
443 drm_device_t *dev = priv->dev;
444 drm_ctx_t ctx;
445 drm_queue_t *q;
446 drm_buf_t *buf;
447
448 if (copy_from_user(&ctx, (drm_ctx_t __user *)arg, sizeof(ctx)))
449 return -EFAULT;
450 DRM_DEBUG("%d\n", ctx.handle);
451
452 if (ctx.handle >= dev->queue_count) return -EINVAL;
453 q = dev->queuelist[ctx.handle];
454
455 atomic_inc(&q->use_count);
456 if (atomic_read(&q->use_count) == 1) {
457 /* No longer in use */
458 atomic_dec(&q->use_count);
459 return -EINVAL;
460 }
461
462 atomic_inc(&q->finalization); /* Mark queue in finalization state */
463 atomic_sub(2, &q->use_count); /* Mark queue as unused (pending
464 finalization) */
465
466 while (test_and_set_bit(0, &dev->interrupt_flag)) {
467 schedule();
468 if (signal_pending(current)) {
469 clear_bit(0, &dev->interrupt_flag);
470 return -EINTR;
471 }
472 }
473 /* Remove queued buffers */
474 while ((buf = DRM(waitlist_get)(&q->waitlist))) {
475 DRM(free_buffer)(dev, buf);
476 }
477 clear_bit(0, &dev->interrupt_flag);
478
479 /* Wakeup blocked processes */
480 wake_up_interruptible(&q->read_queue);
481 wake_up_interruptible(&q->write_queue);
482 wake_up_interruptible(&q->flush_queue);
483
484 /* Finalization over. Queue is made
485 available when both use_count and
486 finalization become 0, which won't
487 happen until all the waiting processes
488 stop waiting. */
489 atomic_dec(&q->finalization);
490 return 0;
491}
492
diff --git a/drivers/char/drm/gamma_dma.c b/drivers/char/drm/gamma_dma.c
deleted file mode 100644
index e486fb8d31e9..000000000000
--- a/drivers/char/drm/gamma_dma.c
+++ /dev/null
@@ -1,946 +0,0 @@
1/* gamma_dma.c -- DMA support for GMX 2000 -*- linux-c -*-
2 * Created: Fri Mar 19 14:30:16 1999 by faith@precisioninsight.com
3 *
4 * Copyright 1999 Precision Insight, Inc., Cedar Park, Texas.
5 * Copyright 2000 VA Linux Systems, Inc., Sunnyvale, California.
6 * All Rights Reserved.
7 *
8 * Permission is hereby granted, free of charge, to any person obtaining a
9 * copy of this software and associated documentation files (the "Software"),
10 * to deal in the Software without restriction, including without limitation
11 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
12 * and/or sell copies of the Software, and to permit persons to whom the
13 * Software is furnished to do so, subject to the following conditions:
14 *
15 * The above copyright notice and this permission notice (including the next
16 * paragraph) shall be included in all copies or substantial portions of the
17 * Software.
18 *
19 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
20 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
21 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
22 * PRECISION INSIGHT AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
23 * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
24 * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
25 * DEALINGS IN THE SOFTWARE.
26 *
27 * Authors:
28 * Rickard E. (Rik) Faith <faith@valinux.com>
29 *
30 */
31
32#include "gamma.h"
33#include "drmP.h"
34#include "drm.h"
35#include "gamma_drm.h"
36#include "gamma_drv.h"
37
38#include <linux/interrupt.h> /* For task queue support */
39#include <linux/delay.h>
40
41static inline void gamma_dma_dispatch(drm_device_t *dev, unsigned long address,
42 unsigned long length)
43{
44 drm_gamma_private_t *dev_priv =
45 (drm_gamma_private_t *)dev->dev_private;
46 mb();
47 while ( GAMMA_READ(GAMMA_INFIFOSPACE) < 2)
48 cpu_relax();
49
50 GAMMA_WRITE(GAMMA_DMAADDRESS, address);
51
52 while (GAMMA_READ(GAMMA_GCOMMANDSTATUS) != 4)
53 cpu_relax();
54
55 GAMMA_WRITE(GAMMA_DMACOUNT, length / 4);
56}
57
58void gamma_dma_quiescent_single(drm_device_t *dev)
59{
60 drm_gamma_private_t *dev_priv =
61 (drm_gamma_private_t *)dev->dev_private;
62 while (GAMMA_READ(GAMMA_DMACOUNT))
63 cpu_relax();
64
65 while (GAMMA_READ(GAMMA_INFIFOSPACE) < 2)
66 cpu_relax();
67
68 GAMMA_WRITE(GAMMA_FILTERMODE, 1 << 10);
69 GAMMA_WRITE(GAMMA_SYNC, 0);
70
71 do {
72 while (!GAMMA_READ(GAMMA_OUTFIFOWORDS))
73 cpu_relax();
74 } while (GAMMA_READ(GAMMA_OUTPUTFIFO) != GAMMA_SYNC_TAG);
75}
76
77void gamma_dma_quiescent_dual(drm_device_t *dev)
78{
79 drm_gamma_private_t *dev_priv =
80 (drm_gamma_private_t *)dev->dev_private;
81 while (GAMMA_READ(GAMMA_DMACOUNT))
82 cpu_relax();
83
84 while (GAMMA_READ(GAMMA_INFIFOSPACE) < 3)
85 cpu_relax();
86
87 GAMMA_WRITE(GAMMA_BROADCASTMASK, 3);
88 GAMMA_WRITE(GAMMA_FILTERMODE, 1 << 10);
89 GAMMA_WRITE(GAMMA_SYNC, 0);
90
91 /* Read from first MX */
92 do {
93 while (!GAMMA_READ(GAMMA_OUTFIFOWORDS))
94 cpu_relax();
95 } while (GAMMA_READ(GAMMA_OUTPUTFIFO) != GAMMA_SYNC_TAG);
96
97 /* Read from second MX */
98 do {
99 while (!GAMMA_READ(GAMMA_OUTFIFOWORDS + 0x10000))
100 cpu_relax();
101 } while (GAMMA_READ(GAMMA_OUTPUTFIFO + 0x10000) != GAMMA_SYNC_TAG);
102}
103
104void gamma_dma_ready(drm_device_t *dev)
105{
106 drm_gamma_private_t *dev_priv =
107 (drm_gamma_private_t *)dev->dev_private;
108 while (GAMMA_READ(GAMMA_DMACOUNT))
109 cpu_relax();
110}
111
112static inline int gamma_dma_is_ready(drm_device_t *dev)
113{
114 drm_gamma_private_t *dev_priv =
115 (drm_gamma_private_t *)dev->dev_private;
116 return (!GAMMA_READ(GAMMA_DMACOUNT));
117}
118
119irqreturn_t gamma_driver_irq_handler( DRM_IRQ_ARGS )
120{
121 drm_device_t *dev = (drm_device_t *)arg;
122 drm_device_dma_t *dma = dev->dma;
123 drm_gamma_private_t *dev_priv =
124 (drm_gamma_private_t *)dev->dev_private;
125
126 /* FIXME: should check whether we're actually interested in the interrupt? */
127 atomic_inc(&dev->counts[6]); /* _DRM_STAT_IRQ */
128
129 while (GAMMA_READ(GAMMA_INFIFOSPACE) < 3)
130 cpu_relax();
131
132 GAMMA_WRITE(GAMMA_GDELAYTIMER, 0xc350/2); /* 0x05S */
133 GAMMA_WRITE(GAMMA_GCOMMANDINTFLAGS, 8);
134 GAMMA_WRITE(GAMMA_GINTFLAGS, 0x2001);
135 if (gamma_dma_is_ready(dev)) {
136 /* Free previous buffer */
137 if (test_and_set_bit(0, &dev->dma_flag))
138 return IRQ_HANDLED;
139 if (dma->this_buffer) {
140 gamma_free_buffer(dev, dma->this_buffer);
141 dma->this_buffer = NULL;
142 }
143 clear_bit(0, &dev->dma_flag);
144
145 /* Dispatch new buffer */
146 schedule_work(&dev->work);
147 }
148 return IRQ_HANDLED;
149}
150
151/* Only called by gamma_dma_schedule. */
152static int gamma_do_dma(drm_device_t *dev, int locked)
153{
154 unsigned long address;
155 unsigned long length;
156 drm_buf_t *buf;
157 int retcode = 0;
158 drm_device_dma_t *dma = dev->dma;
159
160 if (test_and_set_bit(0, &dev->dma_flag)) return -EBUSY;
161
162
163 if (!dma->next_buffer) {
164 DRM_ERROR("No next_buffer\n");
165 clear_bit(0, &dev->dma_flag);
166 return -EINVAL;
167 }
168
169 buf = dma->next_buffer;
170 /* WE NOW ARE ON LOGICAL PAGES!! - using page table setup in dma_init */
171 /* So we pass the buffer index value into the physical page offset */
172 address = buf->idx << 12;
173 length = buf->used;
174
175 DRM_DEBUG("context %d, buffer %d (%ld bytes)\n",
176 buf->context, buf->idx, length);
177
178 if (buf->list == DRM_LIST_RECLAIM) {
179 gamma_clear_next_buffer(dev);
180 gamma_free_buffer(dev, buf);
181 clear_bit(0, &dev->dma_flag);
182 return -EINVAL;
183 }
184
185 if (!length) {
186 DRM_ERROR("0 length buffer\n");
187 gamma_clear_next_buffer(dev);
188 gamma_free_buffer(dev, buf);
189 clear_bit(0, &dev->dma_flag);
190 return 0;
191 }
192
193 if (!gamma_dma_is_ready(dev)) {
194 clear_bit(0, &dev->dma_flag);
195 return -EBUSY;
196 }
197
198 if (buf->while_locked) {
199 if (!_DRM_LOCK_IS_HELD(dev->lock.hw_lock->lock)) {
200 DRM_ERROR("Dispatching buffer %d from pid %d"
201 " \"while locked\", but no lock held\n",
202 buf->idx, current->pid);
203 }
204 } else {
205 if (!locked && !gamma_lock_take(&dev->lock.hw_lock->lock,
206 DRM_KERNEL_CONTEXT)) {
207 clear_bit(0, &dev->dma_flag);
208 return -EBUSY;
209 }
210 }
211
212 if (dev->last_context != buf->context
213 && !(dev->queuelist[buf->context]->flags
214 & _DRM_CONTEXT_PRESERVED)) {
215 /* PRE: dev->last_context != buf->context */
216 if (DRM(context_switch)(dev, dev->last_context,
217 buf->context)) {
218 DRM(clear_next_buffer)(dev);
219 DRM(free_buffer)(dev, buf);
220 }
221 retcode = -EBUSY;
222 goto cleanup;
223
224 /* POST: we will wait for the context
225 switch and will dispatch on a later call
226 when dev->last_context == buf->context.
227 NOTE WE HOLD THE LOCK THROUGHOUT THIS
228 TIME! */
229 }
230
231 gamma_clear_next_buffer(dev);
232 buf->pending = 1;
233 buf->waiting = 0;
234 buf->list = DRM_LIST_PEND;
235
236 /* WE NOW ARE ON LOGICAL PAGES!!! - overriding address */
237 address = buf->idx << 12;
238
239 gamma_dma_dispatch(dev, address, length);
240 gamma_free_buffer(dev, dma->this_buffer);
241 dma->this_buffer = buf;
242
243 atomic_inc(&dev->counts[7]); /* _DRM_STAT_DMA */
244 atomic_add(length, &dev->counts[8]); /* _DRM_STAT_PRIMARY */
245
246 if (!buf->while_locked && !dev->context_flag && !locked) {
247 if (gamma_lock_free(dev, &dev->lock.hw_lock->lock,
248 DRM_KERNEL_CONTEXT)) {
249 DRM_ERROR("\n");
250 }
251 }
252cleanup:
253
254 clear_bit(0, &dev->dma_flag);
255
256
257 return retcode;
258}
259
260static void gamma_dma_timer_bh(unsigned long dev)
261{
262 gamma_dma_schedule((drm_device_t *)dev, 0);
263}
264
265void gamma_irq_immediate_bh(void *dev)
266{
267 gamma_dma_schedule(dev, 0);
268}
269
270int gamma_dma_schedule(drm_device_t *dev, int locked)
271{
272 int next;
273 drm_queue_t *q;
274 drm_buf_t *buf;
275 int retcode = 0;
276 int processed = 0;
277 int missed;
278 int expire = 20;
279 drm_device_dma_t *dma = dev->dma;
280
281 if (test_and_set_bit(0, &dev->interrupt_flag)) {
282 /* Not reentrant */
283 atomic_inc(&dev->counts[10]); /* _DRM_STAT_MISSED */
284 return -EBUSY;
285 }
286 missed = atomic_read(&dev->counts[10]);
287
288
289again:
290 if (dev->context_flag) {
291 clear_bit(0, &dev->interrupt_flag);
292 return -EBUSY;
293 }
294 if (dma->next_buffer) {
295 /* Unsent buffer that was previously
296 selected, but that couldn't be sent
297 because the lock could not be obtained
298 or the DMA engine wasn't ready. Try
299 again. */
300 if (!(retcode = gamma_do_dma(dev, locked))) ++processed;
301 } else {
302 do {
303 next = gamma_select_queue(dev, gamma_dma_timer_bh);
304 if (next >= 0) {
305 q = dev->queuelist[next];
306 buf = gamma_waitlist_get(&q->waitlist);
307 dma->next_buffer = buf;
308 dma->next_queue = q;
309 if (buf && buf->list == DRM_LIST_RECLAIM) {
310 gamma_clear_next_buffer(dev);
311 gamma_free_buffer(dev, buf);
312 }
313 }
314 } while (next >= 0 && !dma->next_buffer);
315 if (dma->next_buffer) {
316 if (!(retcode = gamma_do_dma(dev, locked))) {
317 ++processed;
318 }
319 }
320 }
321
322 if (--expire) {
323 if (missed != atomic_read(&dev->counts[10])) {
324 if (gamma_dma_is_ready(dev)) goto again;
325 }
326 if (processed && gamma_dma_is_ready(dev)) {
327 processed = 0;
328 goto again;
329 }
330 }
331
332 clear_bit(0, &dev->interrupt_flag);
333
334 return retcode;
335}
336
337static int gamma_dma_priority(struct file *filp,
338 drm_device_t *dev, drm_dma_t *d)
339{
340 unsigned long address;
341 unsigned long length;
342 int must_free = 0;
343 int retcode = 0;
344 int i;
345 int idx;
346 drm_buf_t *buf;
347 drm_buf_t *last_buf = NULL;
348 drm_device_dma_t *dma = dev->dma;
349 int *send_indices = NULL;
350 int *send_sizes = NULL;
351
352 DECLARE_WAITQUEUE(entry, current);
353
354 /* Turn off interrupt handling */
355 while (test_and_set_bit(0, &dev->interrupt_flag)) {
356 schedule();
357 if (signal_pending(current)) return -EINTR;
358 }
359 if (!(d->flags & _DRM_DMA_WHILE_LOCKED)) {
360 while (!gamma_lock_take(&dev->lock.hw_lock->lock,
361 DRM_KERNEL_CONTEXT)) {
362 schedule();
363 if (signal_pending(current)) {
364 clear_bit(0, &dev->interrupt_flag);
365 return -EINTR;
366 }
367 }
368 ++must_free;
369 }
370
371 send_indices = DRM(alloc)(d->send_count * sizeof(*send_indices),
372 DRM_MEM_DRIVER);
373 if (send_indices == NULL)
374 return -ENOMEM;
375 if (copy_from_user(send_indices, d->send_indices,
376 d->send_count * sizeof(*send_indices))) {
377 retcode = -EFAULT;
378 goto cleanup;
379 }
380
381 send_sizes = DRM(alloc)(d->send_count * sizeof(*send_sizes),
382 DRM_MEM_DRIVER);
383 if (send_sizes == NULL)
384 return -ENOMEM;
385 if (copy_from_user(send_sizes, d->send_sizes,
386 d->send_count * sizeof(*send_sizes))) {
387 retcode = -EFAULT;
388 goto cleanup;
389 }
390
391 for (i = 0; i < d->send_count; i++) {
392 idx = send_indices[i];
393 if (idx < 0 || idx >= dma->buf_count) {
394 DRM_ERROR("Index %d (of %d max)\n",
395 send_indices[i], dma->buf_count - 1);
396 continue;
397 }
398 buf = dma->buflist[ idx ];
399 if (buf->filp != filp) {
400 DRM_ERROR("Process %d using buffer not owned\n",
401 current->pid);
402 retcode = -EINVAL;
403 goto cleanup;
404 }
405 if (buf->list != DRM_LIST_NONE) {
406 DRM_ERROR("Process %d using buffer on list %d\n",
407 current->pid, buf->list);
408 retcode = -EINVAL;
409 goto cleanup;
410 }
411 /* This isn't a race condition on
412 buf->list, since our concern is the
413 buffer reclaim during the time the
414 process closes the /dev/drm? handle, so
415 it can't also be doing DMA. */
416 buf->list = DRM_LIST_PRIO;
417 buf->used = send_sizes[i];
418 buf->context = d->context;
419 buf->while_locked = d->flags & _DRM_DMA_WHILE_LOCKED;
420 address = (unsigned long)buf->address;
421 length = buf->used;
422 if (!length) {
423 DRM_ERROR("0 length buffer\n");
424 }
425 if (buf->pending) {
426 DRM_ERROR("Sending pending buffer:"
427 " buffer %d, offset %d\n",
428 send_indices[i], i);
429 retcode = -EINVAL;
430 goto cleanup;
431 }
432 if (buf->waiting) {
433 DRM_ERROR("Sending waiting buffer:"
434 " buffer %d, offset %d\n",
435 send_indices[i], i);
436 retcode = -EINVAL;
437 goto cleanup;
438 }
439 buf->pending = 1;
440
441 if (dev->last_context != buf->context
442 && !(dev->queuelist[buf->context]->flags
443 & _DRM_CONTEXT_PRESERVED)) {
444 add_wait_queue(&dev->context_wait, &entry);
445 current->state = TASK_INTERRUPTIBLE;
446 /* PRE: dev->last_context != buf->context */
447 DRM(context_switch)(dev, dev->last_context,
448 buf->context);
449 /* POST: we will wait for the context
450 switch and will dispatch on a later call
451 when dev->last_context == buf->context.
452 NOTE WE HOLD THE LOCK THROUGHOUT THIS
453 TIME! */
454 schedule();
455 current->state = TASK_RUNNING;
456 remove_wait_queue(&dev->context_wait, &entry);
457 if (signal_pending(current)) {
458 retcode = -EINTR;
459 goto cleanup;
460 }
461 if (dev->last_context != buf->context) {
462 DRM_ERROR("Context mismatch: %d %d\n",
463 dev->last_context,
464 buf->context);
465 }
466 }
467
468 gamma_dma_dispatch(dev, address, length);
469 atomic_inc(&dev->counts[9]); /* _DRM_STAT_SPECIAL */
470 atomic_add(length, &dev->counts[8]); /* _DRM_STAT_PRIMARY */
471
472 if (last_buf) {
473 gamma_free_buffer(dev, last_buf);
474 }
475 last_buf = buf;
476 }
477
478
479cleanup:
480 if (last_buf) {
481 gamma_dma_ready(dev);
482 gamma_free_buffer(dev, last_buf);
483 }
484 if (send_indices)
485 DRM(free)(send_indices, d->send_count * sizeof(*send_indices),
486 DRM_MEM_DRIVER);
487 if (send_sizes)
488 DRM(free)(send_sizes, d->send_count * sizeof(*send_sizes),
489 DRM_MEM_DRIVER);
490
491 if (must_free && !dev->context_flag) {
492 if (gamma_lock_free(dev, &dev->lock.hw_lock->lock,
493 DRM_KERNEL_CONTEXT)) {
494 DRM_ERROR("\n");
495 }
496 }
497 clear_bit(0, &dev->interrupt_flag);
498 return retcode;
499}
500
501static int gamma_dma_send_buffers(struct file *filp,
502 drm_device_t *dev, drm_dma_t *d)
503{
504 DECLARE_WAITQUEUE(entry, current);
505 drm_buf_t *last_buf = NULL;
506 int retcode = 0;
507 drm_device_dma_t *dma = dev->dma;
508 int send_index;
509
510 if (get_user(send_index, &d->send_indices[d->send_count-1]))
511 return -EFAULT;
512
513 if (d->flags & _DRM_DMA_BLOCK) {
514 last_buf = dma->buflist[send_index];
515 add_wait_queue(&last_buf->dma_wait, &entry);
516 }
517
518 if ((retcode = gamma_dma_enqueue(filp, d))) {
519 if (d->flags & _DRM_DMA_BLOCK)
520 remove_wait_queue(&last_buf->dma_wait, &entry);
521 return retcode;
522 }
523
524 gamma_dma_schedule(dev, 0);
525
526 if (d->flags & _DRM_DMA_BLOCK) {
527 DRM_DEBUG("%d waiting\n", current->pid);
528 for (;;) {
529 current->state = TASK_INTERRUPTIBLE;
530 if (!last_buf->waiting && !last_buf->pending)
531 break; /* finished */
532 schedule();
533 if (signal_pending(current)) {
534 retcode = -EINTR; /* Can't restart */
535 break;
536 }
537 }
538 current->state = TASK_RUNNING;
539 DRM_DEBUG("%d running\n", current->pid);
540 remove_wait_queue(&last_buf->dma_wait, &entry);
541 if (!retcode
542 || (last_buf->list==DRM_LIST_PEND && !last_buf->pending)) {
543 if (!waitqueue_active(&last_buf->dma_wait)) {
544 gamma_free_buffer(dev, last_buf);
545 }
546 }
547 if (retcode) {
548 DRM_ERROR("ctx%d w%d p%d c%ld i%d l%d pid:%d\n",
549 d->context,
550 last_buf->waiting,
551 last_buf->pending,
552 (long)DRM_WAITCOUNT(dev, d->context),
553 last_buf->idx,
554 last_buf->list,
555 current->pid);
556 }
557 }
558 return retcode;
559}
560
561int gamma_dma(struct inode *inode, struct file *filp, unsigned int cmd,
562 unsigned long arg)
563{
564 drm_file_t *priv = filp->private_data;
565 drm_device_t *dev = priv->dev;
566 drm_device_dma_t *dma = dev->dma;
567 int retcode = 0;
568 drm_dma_t __user *argp = (void __user *)arg;
569 drm_dma_t d;
570
571 if (copy_from_user(&d, argp, sizeof(d)))
572 return -EFAULT;
573
574 if (d.send_count < 0 || d.send_count > dma->buf_count) {
575 DRM_ERROR("Process %d trying to send %d buffers (of %d max)\n",
576 current->pid, d.send_count, dma->buf_count);
577 return -EINVAL;
578 }
579
580 if (d.request_count < 0 || d.request_count > dma->buf_count) {
581 DRM_ERROR("Process %d trying to get %d buffers (of %d max)\n",
582 current->pid, d.request_count, dma->buf_count);
583 return -EINVAL;
584 }
585
586 if (d.send_count) {
587 if (d.flags & _DRM_DMA_PRIORITY)
588 retcode = gamma_dma_priority(filp, dev, &d);
589 else
590 retcode = gamma_dma_send_buffers(filp, dev, &d);
591 }
592
593 d.granted_count = 0;
594
595 if (!retcode && d.request_count) {
596 retcode = gamma_dma_get_buffers(filp, &d);
597 }
598
599 DRM_DEBUG("%d returning, granted = %d\n",
600 current->pid, d.granted_count);
601 if (copy_to_user(argp, &d, sizeof(d)))
602 return -EFAULT;
603
604 return retcode;
605}
606
607/* =============================================================
608 * DMA initialization, cleanup
609 */
610
611static int gamma_do_init_dma( drm_device_t *dev, drm_gamma_init_t *init )
612{
613 drm_gamma_private_t *dev_priv;
614 drm_device_dma_t *dma = dev->dma;
615 drm_buf_t *buf;
616 int i;
617 struct list_head *list;
618 unsigned long *pgt;
619
620 DRM_DEBUG( "%s\n", __FUNCTION__ );
621
622 dev_priv = DRM(alloc)( sizeof(drm_gamma_private_t),
623 DRM_MEM_DRIVER );
624 if ( !dev_priv )
625 return -ENOMEM;
626
627 dev->dev_private = (void *)dev_priv;
628
629 memset( dev_priv, 0, sizeof(drm_gamma_private_t) );
630
631 dev_priv->num_rast = init->num_rast;
632
633 list_for_each(list, &dev->maplist->head) {
634 drm_map_list_t *r_list = list_entry(list, drm_map_list_t, head);
635 if( r_list->map &&
636 r_list->map->type == _DRM_SHM &&
637 r_list->map->flags & _DRM_CONTAINS_LOCK ) {
638 dev_priv->sarea = r_list->map;
639 break;
640 }
641 }
642
643 dev_priv->mmio0 = drm_core_findmap(dev, init->mmio0);
644 dev_priv->mmio1 = drm_core_findmap(dev, init->mmio1);
645 dev_priv->mmio2 = drm_core_findmap(dev, init->mmio2);
646 dev_priv->mmio3 = drm_core_findmap(dev, init->mmio3);
647
648 dev_priv->sarea_priv = (drm_gamma_sarea_t *)
649 ((u8 *)dev_priv->sarea->handle +
650 init->sarea_priv_offset);
651
652 if (init->pcimode) {
653 buf = dma->buflist[GLINT_DRI_BUF_COUNT];
654 pgt = buf->address;
655
656 for (i = 0; i < GLINT_DRI_BUF_COUNT; i++) {
657 buf = dma->buflist[i];
658 *pgt = virt_to_phys((void*)buf->address) | 0x07;
659 pgt++;
660 }
661
662 buf = dma->buflist[GLINT_DRI_BUF_COUNT];
663 } else {
664 dev->agp_buffer_map = drm_core_findmap(dev, init->buffers_offset);
665 drm_core_ioremap( dev->agp_buffer_map, dev);
666
667 buf = dma->buflist[GLINT_DRI_BUF_COUNT];
668 pgt = buf->address;
669
670 for (i = 0; i < GLINT_DRI_BUF_COUNT; i++) {
671 buf = dma->buflist[i];
672 *pgt = (unsigned long)buf->address + 0x07;
673 pgt++;
674 }
675
676 buf = dma->buflist[GLINT_DRI_BUF_COUNT];
677
678 while (GAMMA_READ(GAMMA_INFIFOSPACE) < 1);
679 GAMMA_WRITE( GAMMA_GDMACONTROL, 0xe);
680 }
681 while (GAMMA_READ(GAMMA_INFIFOSPACE) < 2);
682 GAMMA_WRITE( GAMMA_PAGETABLEADDR, virt_to_phys((void*)buf->address) );
683 GAMMA_WRITE( GAMMA_PAGETABLELENGTH, 2 );
684
685 return 0;
686}
687
688int gamma_do_cleanup_dma( drm_device_t *dev )
689{
690 DRM_DEBUG( "%s\n", __FUNCTION__ );
691
692 /* Make sure interrupts are disabled here because the uninstall ioctl
693 * may not have been called from userspace and after dev_private
694 * is freed, it's too late.
695 */
696 if (drm_core_check_feature(dev, DRIVER_HAVE_IRQ))
697 if ( dev->irq_enabled )
698 DRM(irq_uninstall)(dev);
699
700 if ( dev->dev_private ) {
701
702 if ( dev->agp_buffer_map != NULL )
703 drm_core_ioremapfree( dev->agp_buffer_map, dev );
704
705 DRM(free)( dev->dev_private, sizeof(drm_gamma_private_t),
706 DRM_MEM_DRIVER );
707 dev->dev_private = NULL;
708 }
709
710 return 0;
711}
712
713int gamma_dma_init( struct inode *inode, struct file *filp,
714 unsigned int cmd, unsigned long arg )
715{
716 drm_file_t *priv = filp->private_data;
717 drm_device_t *dev = priv->dev;
718 drm_gamma_init_t init;
719
720 LOCK_TEST_WITH_RETURN( dev, filp );
721
722 if ( copy_from_user( &init, (drm_gamma_init_t __user *)arg, sizeof(init) ) )
723 return -EFAULT;
724
725 switch ( init.func ) {
726 case GAMMA_INIT_DMA:
727 return gamma_do_init_dma( dev, &init );
728 case GAMMA_CLEANUP_DMA:
729 return gamma_do_cleanup_dma( dev );
730 }
731
732 return -EINVAL;
733}
734
735static int gamma_do_copy_dma( drm_device_t *dev, drm_gamma_copy_t *copy )
736{
737 drm_device_dma_t *dma = dev->dma;
738 unsigned int *screenbuf;
739
740 DRM_DEBUG( "%s\n", __FUNCTION__ );
741
742 /* We've DRM_RESTRICTED this DMA buffer */
743
744 screenbuf = dma->buflist[ GLINT_DRI_BUF_COUNT + 1 ]->address;
745
746#if 0
747 *buffer++ = 0x180; /* Tag (FilterMode) */
748 *buffer++ = 0x200; /* Allow FBColor through */
749 *buffer++ = 0x53B; /* Tag */
750 *buffer++ = copy->Pitch;
751 *buffer++ = 0x53A; /* Tag */
752 *buffer++ = copy->SrcAddress;
753 *buffer++ = 0x539; /* Tag */
754 *buffer++ = copy->WidthHeight; /* Initiates transfer */
755 *buffer++ = 0x53C; /* Tag - DMAOutputAddress */
756 *buffer++ = virt_to_phys((void*)screenbuf);
757 *buffer++ = 0x53D; /* Tag - DMAOutputCount */
758 *buffer++ = copy->Count; /* Reads HostOutFifo BLOCKS until ..*/
759
760 /* Data now sitting in dma->buflist[ GLINT_DRI_BUF_COUNT + 1 ] */
761 /* Now put it back to the screen */
762
763 *buffer++ = 0x180; /* Tag (FilterMode) */
764 *buffer++ = 0x400; /* Allow Sync through */
765 *buffer++ = 0x538; /* Tag - DMARectangleReadTarget */
766 *buffer++ = 0x155; /* FBSourceData | count */
767 *buffer++ = 0x537; /* Tag */
768 *buffer++ = copy->Pitch;
769 *buffer++ = 0x536; /* Tag */
770 *buffer++ = copy->DstAddress;
771 *buffer++ = 0x535; /* Tag */
772 *buffer++ = copy->WidthHeight; /* Initiates transfer */
773 *buffer++ = 0x530; /* Tag - DMAAddr */
774 *buffer++ = virt_to_phys((void*)screenbuf);
775 *buffer++ = 0x531;
776 *buffer++ = copy->Count; /* initiates DMA transfer of color data */
777#endif
778
779 /* need to dispatch it now */
780
781 return 0;
782}
783
784int gamma_dma_copy( struct inode *inode, struct file *filp,
785 unsigned int cmd, unsigned long arg )
786{
787 drm_file_t *priv = filp->private_data;
788 drm_device_t *dev = priv->dev;
789 drm_gamma_copy_t copy;
790
791 if ( copy_from_user( &copy, (drm_gamma_copy_t __user *)arg, sizeof(copy) ) )
792 return -EFAULT;
793
794 return gamma_do_copy_dma( dev, &copy );
795}
796
797/* =============================================================
798 * Per Context SAREA Support
799 */
800
801int gamma_getsareactx(struct inode *inode, struct file *filp,
802 unsigned int cmd, unsigned long arg)
803{
804 drm_file_t *priv = filp->private_data;
805 drm_device_t *dev = priv->dev;
806 drm_ctx_priv_map_t __user *argp = (void __user *)arg;
807 drm_ctx_priv_map_t request;
808 drm_map_t *map;
809
810 if (copy_from_user(&request, argp, sizeof(request)))
811 return -EFAULT;
812
813 down(&dev->struct_sem);
814 if ((int)request.ctx_id >= dev->max_context) {
815 up(&dev->struct_sem);
816 return -EINVAL;
817 }
818
819 map = dev->context_sareas[request.ctx_id];
820 up(&dev->struct_sem);
821
822 request.handle = map->handle;
823 if (copy_to_user(argp, &request, sizeof(request)))
824 return -EFAULT;
825 return 0;
826}
827
828int gamma_setsareactx(struct inode *inode, struct file *filp,
829 unsigned int cmd, unsigned long arg)
830{
831 drm_file_t *priv = filp->private_data;
832 drm_device_t *dev = priv->dev;
833 drm_ctx_priv_map_t request;
834 drm_map_t *map = NULL;
835 drm_map_list_t *r_list;
836 struct list_head *list;
837
838 if (copy_from_user(&request,
839 (drm_ctx_priv_map_t __user *)arg,
840 sizeof(request)))
841 return -EFAULT;
842
843 down(&dev->struct_sem);
844 r_list = NULL;
845 list_for_each(list, &dev->maplist->head) {
846 r_list = list_entry(list, drm_map_list_t, head);
847 if(r_list->map &&
848 r_list->map->handle == request.handle) break;
849 }
850 if (list == &(dev->maplist->head)) {
851 up(&dev->struct_sem);
852 return -EINVAL;
853 }
854 map = r_list->map;
855 up(&dev->struct_sem);
856
857 if (!map) return -EINVAL;
858
859 down(&dev->struct_sem);
860 if ((int)request.ctx_id >= dev->max_context) {
861 up(&dev->struct_sem);
862 return -EINVAL;
863 }
864 dev->context_sareas[request.ctx_id] = map;
865 up(&dev->struct_sem);
866 return 0;
867}
868
869void gamma_driver_irq_preinstall( drm_device_t *dev ) {
870 drm_gamma_private_t *dev_priv =
871 (drm_gamma_private_t *)dev->dev_private;
872
873 while(GAMMA_READ(GAMMA_INFIFOSPACE) < 2)
874 cpu_relax();
875
876 GAMMA_WRITE( GAMMA_GCOMMANDMODE, 0x00000004 );
877 GAMMA_WRITE( GAMMA_GDMACONTROL, 0x00000000 );
878}
879
880void gamma_driver_irq_postinstall( drm_device_t *dev ) {
881 drm_gamma_private_t *dev_priv =
882 (drm_gamma_private_t *)dev->dev_private;
883
884 while(GAMMA_READ(GAMMA_INFIFOSPACE) < 3)
885 cpu_relax();
886
887 GAMMA_WRITE( GAMMA_GINTENABLE, 0x00002001 );
888 GAMMA_WRITE( GAMMA_COMMANDINTENABLE, 0x00000008 );
889 GAMMA_WRITE( GAMMA_GDELAYTIMER, 0x00039090 );
890}
891
892void gamma_driver_irq_uninstall( drm_device_t *dev ) {
893 drm_gamma_private_t *dev_priv =
894 (drm_gamma_private_t *)dev->dev_private;
895 if (!dev_priv)
896 return;
897
898 while(GAMMA_READ(GAMMA_INFIFOSPACE) < 3)
899 cpu_relax();
900
901 GAMMA_WRITE( GAMMA_GDELAYTIMER, 0x00000000 );
902 GAMMA_WRITE( GAMMA_COMMANDINTENABLE, 0x00000000 );
903 GAMMA_WRITE( GAMMA_GINTENABLE, 0x00000000 );
904}
905
906extern drm_ioctl_desc_t DRM(ioctls)[];
907
908static int gamma_driver_preinit(drm_device_t *dev)
909{
910 /* reset the finish ioctl */
911 DRM(ioctls)[DRM_IOCTL_NR(DRM_IOCTL_FINISH)].func = DRM(finish);
912 return 0;
913}
914
915static void gamma_driver_pretakedown(drm_device_t *dev)
916{
917 gamma_do_cleanup_dma(dev);
918}
919
920static void gamma_driver_dma_ready(drm_device_t *dev)
921{
922 gamma_dma_ready(dev);
923}
924
925static int gamma_driver_dma_quiescent(drm_device_t *dev)
926{
927 drm_gamma_private_t *dev_priv = (
928 drm_gamma_private_t *)dev->dev_private;
929 if (dev_priv->num_rast == 2)
930 gamma_dma_quiescent_dual(dev);
931 else gamma_dma_quiescent_single(dev);
932 return 0;
933}
934
935void gamma_driver_register_fns(drm_device_t *dev)
936{
937 dev->driver_features = DRIVER_USE_AGP | DRIVER_USE_MTRR | DRIVER_PCI_DMA | DRIVER_HAVE_DMA | DRIVER_HAVE_IRQ;
938 DRM(fops).read = gamma_fops_read;
939 DRM(fops).poll = gamma_fops_poll;
940 dev->driver.preinit = gamma_driver_preinit;
941 dev->driver.pretakedown = gamma_driver_pretakedown;
942 dev->driver.dma_ready = gamma_driver_dma_ready;
943 dev->driver.dma_quiescent = gamma_driver_dma_quiescent;
944 dev->driver.dma_flush_block_and_flush = gamma_flush_block_and_flush;
945 dev->driver.dma_flush_unblock = gamma_flush_unblock;
946}
diff --git a/drivers/char/drm/gamma_drm.h b/drivers/char/drm/gamma_drm.h
deleted file mode 100644
index 20819ded0e15..000000000000
--- a/drivers/char/drm/gamma_drm.h
+++ /dev/null
@@ -1,90 +0,0 @@
1#ifndef _GAMMA_DRM_H_
2#define _GAMMA_DRM_H_
3
4typedef struct _drm_gamma_tex_region {
5 unsigned char next, prev; /* indices to form a circular LRU */
6 unsigned char in_use; /* owned by a client, or free? */
7 int age; /* tracked by clients to update local LRU's */
8} drm_gamma_tex_region_t;
9
10typedef struct {
11 unsigned int GDeltaMode;
12 unsigned int GDepthMode;
13 unsigned int GGeometryMode;
14 unsigned int GTransformMode;
15} drm_gamma_context_regs_t;
16
17typedef struct _drm_gamma_sarea {
18 drm_gamma_context_regs_t context_state;
19
20 unsigned int dirty;
21
22
23 /* Maintain an LRU of contiguous regions of texture space. If
24 * you think you own a region of texture memory, and it has an
25 * age different to the one you set, then you are mistaken and
26 * it has been stolen by another client. If global texAge
27 * hasn't changed, there is no need to walk the list.
28 *
29 * These regions can be used as a proxy for the fine-grained
30 * texture information of other clients - by maintaining them
31 * in the same lru which is used to age their own textures,
32 * clients have an approximate lru for the whole of global
33 * texture space, and can make informed decisions as to which
34 * areas to kick out. There is no need to choose whether to
35 * kick out your own texture or someone else's - simply eject
36 * them all in LRU order.
37 */
38
39#define GAMMA_NR_TEX_REGIONS 64
40 drm_gamma_tex_region_t texList[GAMMA_NR_TEX_REGIONS+1];
41 /* Last elt is sentinal */
42 int texAge; /* last time texture was uploaded */
43 int last_enqueue; /* last time a buffer was enqueued */
44 int last_dispatch; /* age of the most recently dispatched buffer */
45 int last_quiescent; /* */
46 int ctxOwner; /* last context to upload state */
47
48 int vertex_prim;
49} drm_gamma_sarea_t;
50
51/* WARNING: If you change any of these defines, make sure to change the
52 * defines in the Xserver file (xf86drmGamma.h)
53 */
54
55/* Gamma specific ioctls
56 * The device specific ioctl range is 0x40 to 0x79.
57 */
58#define DRM_IOCTL_GAMMA_INIT DRM_IOW( 0x40, drm_gamma_init_t)
59#define DRM_IOCTL_GAMMA_COPY DRM_IOW( 0x41, drm_gamma_copy_t)
60
61typedef struct drm_gamma_copy {
62 unsigned int DMAOutputAddress;
63 unsigned int DMAOutputCount;
64 unsigned int DMAReadGLINTSource;
65 unsigned int DMARectangleWriteAddress;
66 unsigned int DMARectangleWriteLinePitch;
67 unsigned int DMARectangleWrite;
68 unsigned int DMARectangleReadAddress;
69 unsigned int DMARectangleReadLinePitch;
70 unsigned int DMARectangleRead;
71 unsigned int DMARectangleReadTarget;
72} drm_gamma_copy_t;
73
74typedef struct drm_gamma_init {
75 enum {
76 GAMMA_INIT_DMA = 0x01,
77 GAMMA_CLEANUP_DMA = 0x02
78 } func;
79
80 int sarea_priv_offset;
81 int pcimode;
82 unsigned int mmio0;
83 unsigned int mmio1;
84 unsigned int mmio2;
85 unsigned int mmio3;
86 unsigned int buffers_offset;
87 int num_rast;
88} drm_gamma_init_t;
89
90#endif /* _GAMMA_DRM_H_ */
diff --git a/drivers/char/drm/gamma_drv.c b/drivers/char/drm/gamma_drv.c
deleted file mode 100644
index e7e64b62792a..000000000000
--- a/drivers/char/drm/gamma_drv.c
+++ /dev/null
@@ -1,59 +0,0 @@
1/* gamma.c -- 3dlabs GMX 2000 driver -*- linux-c -*-
2 * Created: Mon Jan 4 08:58:31 1999 by faith@precisioninsight.com
3 *
4 * Copyright 1999 Precision Insight, Inc., Cedar Park, Texas.
5 * Copyright 2000 VA Linux Systems, Inc., Sunnyvale, California.
6 * All Rights Reserved.
7 *
8 * Permission is hereby granted, free of charge, to any person obtaining a
9 * copy of this software and associated documentation files (the "Software"),
10 * to deal in the Software without restriction, including without limitation
11 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
12 * and/or sell copies of the Software, and to permit persons to whom the
13 * Software is furnished to do so, subject to the following conditions:
14 *
15 * The above copyright notice and this permission notice (including the next
16 * paragraph) shall be included in all copies or substantial portions of the
17 * Software.
18 *
19 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
20 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
21 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
22 * PRECISION INSIGHT AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
23 * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
24 * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
25 * DEALINGS IN THE SOFTWARE.
26 *
27 * Authors:
28 * Rickard E. (Rik) Faith <faith@valinux.com>
29 * Gareth Hughes <gareth@valinux.com>
30 */
31
32#include <linux/config.h>
33#include "gamma.h"
34#include "drmP.h"
35#include "drm.h"
36#include "gamma_drm.h"
37#include "gamma_drv.h"
38
39#include "drm_auth.h"
40#include "drm_agpsupport.h"
41#include "drm_bufs.h"
42#include "gamma_context.h" /* NOTE! */
43#include "drm_dma.h"
44#include "gamma_old_dma.h" /* NOTE */
45#include "drm_drawable.h"
46#include "drm_drv.h"
47
48#include "drm_fops.h"
49#include "drm_init.h"
50#include "drm_ioctl.h"
51#include "drm_irq.h"
52#include "gamma_lists.h" /* NOTE */
53#include "drm_lock.h"
54#include "gamma_lock.h" /* NOTE */
55#include "drm_memory.h"
56#include "drm_proc.h"
57#include "drm_vm.h"
58#include "drm_stub.h"
59#include "drm_scatter.h"
diff --git a/drivers/char/drm/gamma_drv.h b/drivers/char/drm/gamma_drv.h
deleted file mode 100644
index 146fcc6253cd..000000000000
--- a/drivers/char/drm/gamma_drv.h
+++ /dev/null
@@ -1,147 +0,0 @@
1/* gamma_drv.h -- Private header for 3dlabs GMX 2000 driver -*- linux-c -*-
2 * Created: Mon Jan 4 10:05:05 1999 by faith@precisioninsight.com
3 *
4 * Copyright 1999 Precision Insight, Inc., Cedar Park, Texas.
5 * Copyright 2000 VA Linux Systems, Inc., Sunnyvale, California.
6 * All rights reserved.
7 *
8 * Permission is hereby granted, free of charge, to any person obtaining a
9 * copy of this software and associated documentation files (the "Software"),
10 * to deal in the Software without restriction, including without limitation
11 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
12 * and/or sell copies of the Software, and to permit persons to whom the
13 * Software is furnished to do so, subject to the following conditions:
14 *
15 * The above copyright notice and this permission notice (including the next
16 * paragraph) shall be included in all copies or substantial portions of the
17 * Software.
18 *
19 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
20 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
21 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
22 * PRECISION INSIGHT AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
23 * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
24 * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
25 * DEALINGS IN THE SOFTWARE.
26 *
27 * Authors:
28 * Rickard E. (Rik) Faith <faith@valinux.com>
29 *
30 */
31
32#ifndef _GAMMA_DRV_H_
33#define _GAMMA_DRV_H_
34
35typedef struct drm_gamma_private {
36 drm_gamma_sarea_t *sarea_priv;
37 drm_map_t *sarea;
38 drm_map_t *mmio0;
39 drm_map_t *mmio1;
40 drm_map_t *mmio2;
41 drm_map_t *mmio3;
42 int num_rast;
43} drm_gamma_private_t;
44
45 /* gamma_dma.c */
46extern int gamma_dma_init( struct inode *inode, struct file *filp,
47 unsigned int cmd, unsigned long arg );
48extern int gamma_dma_copy( struct inode *inode, struct file *filp,
49 unsigned int cmd, unsigned long arg );
50
51extern int gamma_do_cleanup_dma( drm_device_t *dev );
52extern void gamma_dma_ready(drm_device_t *dev);
53extern void gamma_dma_quiescent_single(drm_device_t *dev);
54extern void gamma_dma_quiescent_dual(drm_device_t *dev);
55
56 /* gamma_dma.c */
57extern int gamma_dma_schedule(drm_device_t *dev, int locked);
58extern int gamma_dma(struct inode *inode, struct file *filp,
59 unsigned int cmd, unsigned long arg);
60extern int gamma_find_devices(void);
61extern int gamma_found(void);
62
63/* Gamma-specific code pulled from drm_fops.h:
64 */
65extern int DRM(finish)(struct inode *inode, struct file *filp,
66 unsigned int cmd, unsigned long arg);
67extern int DRM(flush_unblock)(drm_device_t *dev, int context,
68 drm_lock_flags_t flags);
69extern int DRM(flush_block_and_flush)(drm_device_t *dev, int context,
70 drm_lock_flags_t flags);
71
72/* Gamma-specific code pulled from drm_dma.h:
73 */
74extern void DRM(clear_next_buffer)(drm_device_t *dev);
75extern int DRM(select_queue)(drm_device_t *dev,
76 void (*wrapper)(unsigned long));
77extern int DRM(dma_enqueue)(struct file *filp, drm_dma_t *dma);
78extern int DRM(dma_get_buffers)(struct file *filp, drm_dma_t *dma);
79
80
81/* Gamma-specific code pulled from drm_lists.h (now renamed gamma_lists.h):
82 */
83extern int DRM(waitlist_create)(drm_waitlist_t *bl, int count);
84extern int DRM(waitlist_destroy)(drm_waitlist_t *bl);
85extern int DRM(waitlist_put)(drm_waitlist_t *bl, drm_buf_t *buf);
86extern drm_buf_t *DRM(waitlist_get)(drm_waitlist_t *bl);
87extern int DRM(freelist_create)(drm_freelist_t *bl, int count);
88extern int DRM(freelist_destroy)(drm_freelist_t *bl);
89extern int DRM(freelist_put)(drm_device_t *dev, drm_freelist_t *bl,
90 drm_buf_t *buf);
91extern drm_buf_t *DRM(freelist_get)(drm_freelist_t *bl, int block);
92
93/* externs for gamma changes to the ops */
94extern struct file_operations DRM(fops);
95extern unsigned int gamma_fops_poll(struct file *filp, struct poll_table_struct *wait);
96extern ssize_t gamma_fops_read(struct file *filp, char __user *buf, size_t count, loff_t *off);
97
98
99#define GLINT_DRI_BUF_COUNT 256
100
101#define GAMMA_OFF(reg) \
102 ((reg < 0x1000) \
103 ? reg \
104 : ((reg < 0x10000) \
105 ? (reg - 0x1000) \
106 : ((reg < 0x11000) \
107 ? (reg - 0x10000) \
108 : (reg - 0x11000))))
109
110#define GAMMA_BASE(reg) ((unsigned long) \
111 ((reg < 0x1000) ? dev_priv->mmio0->handle : \
112 ((reg < 0x10000) ? dev_priv->mmio1->handle : \
113 ((reg < 0x11000) ? dev_priv->mmio2->handle : \
114 dev_priv->mmio3->handle))))
115#define GAMMA_ADDR(reg) (GAMMA_BASE(reg) + GAMMA_OFF(reg))
116#define GAMMA_DEREF(reg) *(__volatile__ int *)GAMMA_ADDR(reg)
117#define GAMMA_READ(reg) GAMMA_DEREF(reg)
118#define GAMMA_WRITE(reg,val) do { GAMMA_DEREF(reg) = val; } while (0)
119
120#define GAMMA_BROADCASTMASK 0x9378
121#define GAMMA_COMMANDINTENABLE 0x0c48
122#define GAMMA_DMAADDRESS 0x0028
123#define GAMMA_DMACOUNT 0x0030
124#define GAMMA_FILTERMODE 0x8c00
125#define GAMMA_GCOMMANDINTFLAGS 0x0c50
126#define GAMMA_GCOMMANDMODE 0x0c40
127#define GAMMA_QUEUED_DMA_MODE 1<<1
128#define GAMMA_GCOMMANDSTATUS 0x0c60
129#define GAMMA_GDELAYTIMER 0x0c38
130#define GAMMA_GDMACONTROL 0x0060
131#define GAMMA_USE_AGP 1<<1
132#define GAMMA_GINTENABLE 0x0808
133#define GAMMA_GINTFLAGS 0x0810
134#define GAMMA_INFIFOSPACE 0x0018
135#define GAMMA_OUTFIFOWORDS 0x0020
136#define GAMMA_OUTPUTFIFO 0x2000
137#define GAMMA_SYNC 0x8c40
138#define GAMMA_SYNC_TAG 0x0188
139#define GAMMA_PAGETABLEADDR 0x0C00
140#define GAMMA_PAGETABLELENGTH 0x0C08
141
142#define GAMMA_PASSTHROUGH 0x1FE
143#define GAMMA_DMAADDRTAG 0x530
144#define GAMMA_DMACOUNTTAG 0x531
145#define GAMMA_COMMANDINTTAG 0x532
146
147#endif
diff --git a/drivers/char/drm/gamma_lists.h b/drivers/char/drm/gamma_lists.h
deleted file mode 100644
index 2d93f412b96b..000000000000
--- a/drivers/char/drm/gamma_lists.h
+++ /dev/null
@@ -1,215 +0,0 @@
1/* drm_lists.h -- Buffer list handling routines -*- linux-c -*-
2 * Created: Mon Apr 19 20:54:22 1999 by faith@valinux.com
3 *
4 * Copyright 1999 Precision Insight, Inc., Cedar Park, Texas.
5 * Copyright 2000 VA Linux Systems, Inc., Sunnyvale, California.
6 * All Rights Reserved.
7 *
8 * Permission is hereby granted, free of charge, to any person obtaining a
9 * copy of this software and associated documentation files (the "Software"),
10 * to deal in the Software without restriction, including without limitation
11 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
12 * and/or sell copies of the Software, and to permit persons to whom the
13 * Software is furnished to do so, subject to the following conditions:
14 *
15 * The above copyright notice and this permission notice (including the next
16 * paragraph) shall be included in all copies or substantial portions of the
17 * Software.
18 *
19 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
20 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
21 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
22 * VA LINUX SYSTEMS AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
23 * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
24 * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
25 * OTHER DEALINGS IN THE SOFTWARE.
26 *
27 * Authors:
28 * Rickard E. (Rik) Faith <faith@valinux.com>
29 * Gareth Hughes <gareth@valinux.com>
30 */
31
32#include "drmP.h"
33
34
35int DRM(waitlist_create)(drm_waitlist_t *bl, int count)
36{
37 if (bl->count) return -EINVAL;
38
39 bl->bufs = DRM(alloc)((bl->count + 2) * sizeof(*bl->bufs),
40 DRM_MEM_BUFLISTS);
41
42 if(!bl->bufs) return -ENOMEM;
43 memset(bl->bufs, 0, sizeof(*bl->bufs));
44 bl->count = count;
45 bl->rp = bl->bufs;
46 bl->wp = bl->bufs;
47 bl->end = &bl->bufs[bl->count+1];
48 spin_lock_init(&bl->write_lock);
49 spin_lock_init(&bl->read_lock);
50 return 0;
51}
52
53int DRM(waitlist_destroy)(drm_waitlist_t *bl)
54{
55 if (bl->rp != bl->wp) return -EINVAL;
56 if (bl->bufs) DRM(free)(bl->bufs,
57 (bl->count + 2) * sizeof(*bl->bufs),
58 DRM_MEM_BUFLISTS);
59 bl->count = 0;
60 bl->bufs = NULL;
61 bl->rp = NULL;
62 bl->wp = NULL;
63 bl->end = NULL;
64 return 0;
65}
66
67int DRM(waitlist_put)(drm_waitlist_t *bl, drm_buf_t *buf)
68{
69 int left;
70 unsigned long flags;
71
72 left = DRM_LEFTCOUNT(bl);
73 if (!left) {
74 DRM_ERROR("Overflow while adding buffer %d from filp %p\n",
75 buf->idx, buf->filp);
76 return -EINVAL;
77 }
78 buf->list = DRM_LIST_WAIT;
79
80 spin_lock_irqsave(&bl->write_lock, flags);
81 *bl->wp = buf;
82 if (++bl->wp >= bl->end) bl->wp = bl->bufs;
83 spin_unlock_irqrestore(&bl->write_lock, flags);
84
85 return 0;
86}
87
88drm_buf_t *DRM(waitlist_get)(drm_waitlist_t *bl)
89{
90 drm_buf_t *buf;
91 unsigned long flags;
92
93 spin_lock_irqsave(&bl->read_lock, flags);
94 buf = *bl->rp;
95 if (bl->rp == bl->wp) {
96 spin_unlock_irqrestore(&bl->read_lock, flags);
97 return NULL;
98 }
99 if (++bl->rp >= bl->end) bl->rp = bl->bufs;
100 spin_unlock_irqrestore(&bl->read_lock, flags);
101
102 return buf;
103}
104
105int DRM(freelist_create)(drm_freelist_t *bl, int count)
106{
107 atomic_set(&bl->count, 0);
108 bl->next = NULL;
109 init_waitqueue_head(&bl->waiting);
110 bl->low_mark = 0;
111 bl->high_mark = 0;
112 atomic_set(&bl->wfh, 0);
113 spin_lock_init(&bl->lock);
114 ++bl->initialized;
115 return 0;
116}
117
118int DRM(freelist_destroy)(drm_freelist_t *bl)
119{
120 atomic_set(&bl->count, 0);
121 bl->next = NULL;
122 return 0;
123}
124
125int DRM(freelist_put)(drm_device_t *dev, drm_freelist_t *bl, drm_buf_t *buf)
126{
127 drm_device_dma_t *dma = dev->dma;
128
129 if (!dma) {
130 DRM_ERROR("No DMA support\n");
131 return 1;
132 }
133
134 if (buf->waiting || buf->pending || buf->list == DRM_LIST_FREE) {
135 DRM_ERROR("Freed buffer %d: w%d, p%d, l%d\n",
136 buf->idx, buf->waiting, buf->pending, buf->list);
137 }
138 if (!bl) return 1;
139 buf->list = DRM_LIST_FREE;
140
141 spin_lock(&bl->lock);
142 buf->next = bl->next;
143 bl->next = buf;
144 spin_unlock(&bl->lock);
145
146 atomic_inc(&bl->count);
147 if (atomic_read(&bl->count) > dma->buf_count) {
148 DRM_ERROR("%d of %d buffers free after addition of %d\n",
149 atomic_read(&bl->count), dma->buf_count, buf->idx);
150 return 1;
151 }
152 /* Check for high water mark */
153 if (atomic_read(&bl->wfh) && atomic_read(&bl->count)>=bl->high_mark) {
154 atomic_set(&bl->wfh, 0);
155 wake_up_interruptible(&bl->waiting);
156 }
157 return 0;
158}
159
160static drm_buf_t *DRM(freelist_try)(drm_freelist_t *bl)
161{
162 drm_buf_t *buf;
163
164 if (!bl) return NULL;
165
166 /* Get buffer */
167 spin_lock(&bl->lock);
168 if (!bl->next) {
169 spin_unlock(&bl->lock);
170 return NULL;
171 }
172 buf = bl->next;
173 bl->next = bl->next->next;
174 spin_unlock(&bl->lock);
175
176 atomic_dec(&bl->count);
177 buf->next = NULL;
178 buf->list = DRM_LIST_NONE;
179 if (buf->waiting || buf->pending) {
180 DRM_ERROR("Free buffer %d: w%d, p%d, l%d\n",
181 buf->idx, buf->waiting, buf->pending, buf->list);
182 }
183
184 return buf;
185}
186
187drm_buf_t *DRM(freelist_get)(drm_freelist_t *bl, int block)
188{
189 drm_buf_t *buf = NULL;
190 DECLARE_WAITQUEUE(entry, current);
191
192 if (!bl || !bl->initialized) return NULL;
193
194 /* Check for low water mark */
195 if (atomic_read(&bl->count) <= bl->low_mark) /* Became low */
196 atomic_set(&bl->wfh, 1);
197 if (atomic_read(&bl->wfh)) {
198 if (block) {
199 add_wait_queue(&bl->waiting, &entry);
200 for (;;) {
201 current->state = TASK_INTERRUPTIBLE;
202 if (!atomic_read(&bl->wfh)
203 && (buf = DRM(freelist_try)(bl))) break;
204 schedule();
205 if (signal_pending(current)) break;
206 }
207 current->state = TASK_RUNNING;
208 remove_wait_queue(&bl->waiting, &entry);
209 }
210 return buf;
211 }
212
213 return DRM(freelist_try)(bl);
214}
215
diff --git a/drivers/char/drm/gamma_lock.h b/drivers/char/drm/gamma_lock.h
deleted file mode 100644
index ddec67e4ed16..000000000000
--- a/drivers/char/drm/gamma_lock.h
+++ /dev/null
@@ -1,140 +0,0 @@
1/* lock.c -- IOCTLs for locking -*- linux-c -*-
2 * Created: Tue Feb 2 08:37:54 1999 by faith@valinux.com
3 *
4 * Copyright 1999 Precision Insight, Inc., Cedar Park, Texas.
5 * Copyright 2000 VA Linux Systems, Inc., Sunnyvale, California.
6 * All Rights Reserved.
7 *
8 * Permission is hereby granted, free of charge, to any person obtaining a
9 * copy of this software and associated documentation files (the "Software"),
10 * to deal in the Software without restriction, including without limitation
11 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
12 * and/or sell copies of the Software, and to permit persons to whom the
13 * Software is furnished to do so, subject to the following conditions:
14 *
15 * The above copyright notice and this permission notice (including the next
16 * paragraph) shall be included in all copies or substantial portions of the
17 * Software.
18 *
19 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
20 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
21 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
22 * VA LINUX SYSTEMS AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
23 * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
24 * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
25 * OTHER DEALINGS IN THE SOFTWARE.
26 *
27 * Authors:
28 * Rickard E. (Rik) Faith <faith@valinux.com>
29 * Gareth Hughes <gareth@valinux.com>
30 */
31
32
33/* Gamma-specific code extracted from drm_lock.h:
34 */
35static int DRM(flush_queue)(drm_device_t *dev, int context)
36{
37 DECLARE_WAITQUEUE(entry, current);
38 int ret = 0;
39 drm_queue_t *q = dev->queuelist[context];
40
41 DRM_DEBUG("\n");
42
43 atomic_inc(&q->use_count);
44 if (atomic_read(&q->use_count) > 1) {
45 atomic_inc(&q->block_write);
46 add_wait_queue(&q->flush_queue, &entry);
47 atomic_inc(&q->block_count);
48 for (;;) {
49 current->state = TASK_INTERRUPTIBLE;
50 if (!DRM_BUFCOUNT(&q->waitlist)) break;
51 schedule();
52 if (signal_pending(current)) {
53 ret = -EINTR; /* Can't restart */
54 break;
55 }
56 }
57 atomic_dec(&q->block_count);
58 current->state = TASK_RUNNING;
59 remove_wait_queue(&q->flush_queue, &entry);
60 }
61 atomic_dec(&q->use_count);
62
63 /* NOTE: block_write is still incremented!
64 Use drm_flush_unlock_queue to decrement. */
65 return ret;
66}
67
68static int DRM(flush_unblock_queue)(drm_device_t *dev, int context)
69{
70 drm_queue_t *q = dev->queuelist[context];
71
72 DRM_DEBUG("\n");
73
74 atomic_inc(&q->use_count);
75 if (atomic_read(&q->use_count) > 1) {
76 if (atomic_read(&q->block_write)) {
77 atomic_dec(&q->block_write);
78 wake_up_interruptible(&q->write_queue);
79 }
80 }
81 atomic_dec(&q->use_count);
82 return 0;
83}
84
85int DRM(flush_block_and_flush)(drm_device_t *dev, int context,
86 drm_lock_flags_t flags)
87{
88 int ret = 0;
89 int i;
90
91 DRM_DEBUG("\n");
92
93 if (flags & _DRM_LOCK_FLUSH) {
94 ret = DRM(flush_queue)(dev, DRM_KERNEL_CONTEXT);
95 if (!ret) ret = DRM(flush_queue)(dev, context);
96 }
97 if (flags & _DRM_LOCK_FLUSH_ALL) {
98 for (i = 0; !ret && i < dev->queue_count; i++) {
99 ret = DRM(flush_queue)(dev, i);
100 }
101 }
102 return ret;
103}
104
105int DRM(flush_unblock)(drm_device_t *dev, int context, drm_lock_flags_t flags)
106{
107 int ret = 0;
108 int i;
109
110 DRM_DEBUG("\n");
111
112 if (flags & _DRM_LOCK_FLUSH) {
113 ret = DRM(flush_unblock_queue)(dev, DRM_KERNEL_CONTEXT);
114 if (!ret) ret = DRM(flush_unblock_queue)(dev, context);
115 }
116 if (flags & _DRM_LOCK_FLUSH_ALL) {
117 for (i = 0; !ret && i < dev->queue_count; i++) {
118 ret = DRM(flush_unblock_queue)(dev, i);
119 }
120 }
121
122 return ret;
123}
124
125int DRM(finish)(struct inode *inode, struct file *filp, unsigned int cmd,
126 unsigned long arg)
127{
128 drm_file_t *priv = filp->private_data;
129 drm_device_t *dev = priv->dev;
130 int ret = 0;
131 drm_lock_t lock;
132
133 DRM_DEBUG("\n");
134
135 if (copy_from_user(&lock, (drm_lock_t __user *)arg, sizeof(lock)))
136 return -EFAULT;
137 ret = DRM(flush_block_and_flush)(dev, lock.context, lock.flags);
138 DRM(flush_unblock)(dev, lock.context, lock.flags);
139 return ret;
140}
diff --git a/drivers/char/drm/gamma_old_dma.h b/drivers/char/drm/gamma_old_dma.h
deleted file mode 100644
index abdd454aab9f..000000000000
--- a/drivers/char/drm/gamma_old_dma.h
+++ /dev/null
@@ -1,313 +0,0 @@
1/* drm_dma.c -- DMA IOCTL and function support -*- linux-c -*-
2 * Created: Fri Mar 19 14:30:16 1999 by faith@valinux.com
3 *
4 * Copyright 1999, 2000 Precision Insight, Inc., Cedar Park, Texas.
5 * Copyright 2000 VA Linux Systems, Inc., Sunnyvale, California.
6 * All Rights Reserved.
7 *
8 * Permission is hereby granted, free of charge, to any person obtaining a
9 * copy of this software and associated documentation files (the "Software"),
10 * to deal in the Software without restriction, including without limitation
11 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
12 * and/or sell copies of the Software, and to permit persons to whom the
13 * Software is furnished to do so, subject to the following conditions:
14 *
15 * The above copyright notice and this permission notice (including the next
16 * paragraph) shall be included in all copies or substantial portions of the
17 * Software.
18 *
19 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
20 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
21 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
22 * VA LINUX SYSTEMS AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
23 * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
24 * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
25 * OTHER DEALINGS IN THE SOFTWARE.
26 *
27 * Authors:
28 * Rickard E. (Rik) Faith <faith@valinux.com>
29 * Gareth Hughes <gareth@valinux.com>
30 */
31
32
33/* Gamma-specific code pulled from drm_dma.h:
34 */
35
36void DRM(clear_next_buffer)(drm_device_t *dev)
37{
38 drm_device_dma_t *dma = dev->dma;
39
40 dma->next_buffer = NULL;
41 if (dma->next_queue && !DRM_BUFCOUNT(&dma->next_queue->waitlist)) {
42 wake_up_interruptible(&dma->next_queue->flush_queue);
43 }
44 dma->next_queue = NULL;
45}
46
47int DRM(select_queue)(drm_device_t *dev, void (*wrapper)(unsigned long))
48{
49 int i;
50 int candidate = -1;
51 int j = jiffies;
52
53 if (!dev) {
54 DRM_ERROR("No device\n");
55 return -1;
56 }
57 if (!dev->queuelist || !dev->queuelist[DRM_KERNEL_CONTEXT]) {
58 /* This only happens between the time the
59 interrupt is initialized and the time
60 the queues are initialized. */
61 return -1;
62 }
63
64 /* Doing "while locked" DMA? */
65 if (DRM_WAITCOUNT(dev, DRM_KERNEL_CONTEXT)) {
66 return DRM_KERNEL_CONTEXT;
67 }
68
69 /* If there are buffers on the last_context
70 queue, and we have not been executing
71 this context very long, continue to
72 execute this context. */
73 if (dev->last_switch <= j
74 && dev->last_switch + DRM_TIME_SLICE > j
75 && DRM_WAITCOUNT(dev, dev->last_context)) {
76 return dev->last_context;
77 }
78
79 /* Otherwise, find a candidate */
80 for (i = dev->last_checked + 1; i < dev->queue_count; i++) {
81 if (DRM_WAITCOUNT(dev, i)) {
82 candidate = dev->last_checked = i;
83 break;
84 }
85 }
86
87 if (candidate < 0) {
88 for (i = 0; i < dev->queue_count; i++) {
89 if (DRM_WAITCOUNT(dev, i)) {
90 candidate = dev->last_checked = i;
91 break;
92 }
93 }
94 }
95
96 if (wrapper
97 && candidate >= 0
98 && candidate != dev->last_context
99 && dev->last_switch <= j
100 && dev->last_switch + DRM_TIME_SLICE > j) {
101 if (dev->timer.expires != dev->last_switch + DRM_TIME_SLICE) {
102 del_timer(&dev->timer);
103 dev->timer.function = wrapper;
104 dev->timer.data = (unsigned long)dev;
105 dev->timer.expires = dev->last_switch+DRM_TIME_SLICE;
106 add_timer(&dev->timer);
107 }
108 return -1;
109 }
110
111 return candidate;
112}
113
114
115int DRM(dma_enqueue)(struct file *filp, drm_dma_t *d)
116{
117 drm_file_t *priv = filp->private_data;
118 drm_device_t *dev = priv->dev;
119 int i;
120 drm_queue_t *q;
121 drm_buf_t *buf;
122 int idx;
123 int while_locked = 0;
124 drm_device_dma_t *dma = dev->dma;
125 int *ind;
126 int err;
127 DECLARE_WAITQUEUE(entry, current);
128
129 DRM_DEBUG("%d\n", d->send_count);
130
131 if (d->flags & _DRM_DMA_WHILE_LOCKED) {
132 int context = dev->lock.hw_lock->lock;
133
134 if (!_DRM_LOCK_IS_HELD(context)) {
135 DRM_ERROR("No lock held during \"while locked\""
136 " request\n");
137 return -EINVAL;
138 }
139 if (d->context != _DRM_LOCKING_CONTEXT(context)
140 && _DRM_LOCKING_CONTEXT(context) != DRM_KERNEL_CONTEXT) {
141 DRM_ERROR("Lock held by %d while %d makes"
142 " \"while locked\" request\n",
143 _DRM_LOCKING_CONTEXT(context),
144 d->context);
145 return -EINVAL;
146 }
147 q = dev->queuelist[DRM_KERNEL_CONTEXT];
148 while_locked = 1;
149 } else {
150 q = dev->queuelist[d->context];
151 }
152
153
154 atomic_inc(&q->use_count);
155 if (atomic_read(&q->block_write)) {
156 add_wait_queue(&q->write_queue, &entry);
157 atomic_inc(&q->block_count);
158 for (;;) {
159 current->state = TASK_INTERRUPTIBLE;
160 if (!atomic_read(&q->block_write)) break;
161 schedule();
162 if (signal_pending(current)) {
163 atomic_dec(&q->use_count);
164 remove_wait_queue(&q->write_queue, &entry);
165 return -EINTR;
166 }
167 }
168 atomic_dec(&q->block_count);
169 current->state = TASK_RUNNING;
170 remove_wait_queue(&q->write_queue, &entry);
171 }
172
173 ind = DRM(alloc)(d->send_count * sizeof(int), DRM_MEM_DRIVER);
174 if (!ind)
175 return -ENOMEM;
176
177 if (copy_from_user(ind, d->send_indices, d->send_count * sizeof(int))) {
178 err = -EFAULT;
179 goto out;
180 }
181
182 err = -EINVAL;
183 for (i = 0; i < d->send_count; i++) {
184 idx = ind[i];
185 if (idx < 0 || idx >= dma->buf_count) {
186 DRM_ERROR("Index %d (of %d max)\n",
187 ind[i], dma->buf_count - 1);
188 goto out;
189 }
190 buf = dma->buflist[ idx ];
191 if (buf->filp != filp) {
192 DRM_ERROR("Process %d using buffer not owned\n",
193 current->pid);
194 goto out;
195 }
196 if (buf->list != DRM_LIST_NONE) {
197 DRM_ERROR("Process %d using buffer %d on list %d\n",
198 current->pid, buf->idx, buf->list);
199 goto out;
200 }
201 buf->used = ind[i];
202 buf->while_locked = while_locked;
203 buf->context = d->context;
204 if (!buf->used) {
205 DRM_ERROR("Queueing 0 length buffer\n");
206 }
207 if (buf->pending) {
208 DRM_ERROR("Queueing pending buffer:"
209 " buffer %d, offset %d\n",
210 ind[i], i);
211 goto out;
212 }
213 if (buf->waiting) {
214 DRM_ERROR("Queueing waiting buffer:"
215 " buffer %d, offset %d\n",
216 ind[i], i);
217 goto out;
218 }
219 buf->waiting = 1;
220 if (atomic_read(&q->use_count) == 1
221 || atomic_read(&q->finalization)) {
222 DRM(free_buffer)(dev, buf);
223 } else {
224 DRM(waitlist_put)(&q->waitlist, buf);
225 atomic_inc(&q->total_queued);
226 }
227 }
228 atomic_dec(&q->use_count);
229
230 return 0;
231
232out:
233 DRM(free)(ind, d->send_count * sizeof(int), DRM_MEM_DRIVER);
234 atomic_dec(&q->use_count);
235 return err;
236}
237
238static int DRM(dma_get_buffers_of_order)(struct file *filp, drm_dma_t *d,
239 int order)
240{
241 drm_file_t *priv = filp->private_data;
242 drm_device_t *dev = priv->dev;
243 int i;
244 drm_buf_t *buf;
245 drm_device_dma_t *dma = dev->dma;
246
247 for (i = d->granted_count; i < d->request_count; i++) {
248 buf = DRM(freelist_get)(&dma->bufs[order].freelist,
249 d->flags & _DRM_DMA_WAIT);
250 if (!buf) break;
251 if (buf->pending || buf->waiting) {
252 DRM_ERROR("Free buffer %d in use: filp %p (w%d, p%d)\n",
253 buf->idx,
254 buf->filp,
255 buf->waiting,
256 buf->pending);
257 }
258 buf->filp = filp;
259 if (copy_to_user(&d->request_indices[i],
260 &buf->idx,
261 sizeof(buf->idx)))
262 return -EFAULT;
263
264 if (copy_to_user(&d->request_sizes[i],
265 &buf->total,
266 sizeof(buf->total)))
267 return -EFAULT;
268
269 ++d->granted_count;
270 }
271 return 0;
272}
273
274
275int DRM(dma_get_buffers)(struct file *filp, drm_dma_t *dma)
276{
277 int order;
278 int retcode = 0;
279 int tmp_order;
280
281 order = DRM(order)(dma->request_size);
282
283 dma->granted_count = 0;
284 retcode = DRM(dma_get_buffers_of_order)(filp, dma, order);
285
286 if (dma->granted_count < dma->request_count
287 && (dma->flags & _DRM_DMA_SMALLER_OK)) {
288 for (tmp_order = order - 1;
289 !retcode
290 && dma->granted_count < dma->request_count
291 && tmp_order >= DRM_MIN_ORDER;
292 --tmp_order) {
293
294 retcode = DRM(dma_get_buffers_of_order)(filp, dma,
295 tmp_order);
296 }
297 }
298
299 if (dma->granted_count < dma->request_count
300 && (dma->flags & _DRM_DMA_LARGER_OK)) {
301 for (tmp_order = order + 1;
302 !retcode
303 && dma->granted_count < dma->request_count
304 && tmp_order <= DRM_MAX_ORDER;
305 ++tmp_order) {
306
307 retcode = DRM(dma_get_buffers_of_order)(filp, dma,
308 tmp_order);
309 }
310 }
311 return 0;
312}
313
diff --git a/drivers/char/drm/i810_dma.c b/drivers/char/drm/i810_dma.c
index 18e0b7622893..2f1659b96fd1 100644
--- a/drivers/char/drm/i810_dma.c
+++ b/drivers/char/drm/i810_dma.c
@@ -45,11 +45,6 @@
45#define I810_BUF_UNMAPPED 0 45#define I810_BUF_UNMAPPED 0
46#define I810_BUF_MAPPED 1 46#define I810_BUF_MAPPED 1
47 47
48#if LINUX_VERSION_CODE <= KERNEL_VERSION(2,4,2)
49#define down_write down
50#define up_write up
51#endif
52
53static drm_buf_t *i810_freelist_get(drm_device_t *dev) 48static drm_buf_t *i810_freelist_get(drm_device_t *dev)
54{ 49{
55 drm_device_dma_t *dma = dev->dma; 50 drm_device_dma_t *dma = dev->dma;
@@ -351,6 +346,7 @@ static int i810_dma_initialize(drm_device_t *dev,
351 DRM_ERROR("can not find mmio map!\n"); 346 DRM_ERROR("can not find mmio map!\n");
352 return -EINVAL; 347 return -EINVAL;
353 } 348 }
349 dev->agp_buffer_token = init->buffers_offset;
354 dev->agp_buffer_map = drm_core_findmap(dev, init->buffers_offset); 350 dev->agp_buffer_map = drm_core_findmap(dev, init->buffers_offset);
355 if (!dev->agp_buffer_map) { 351 if (!dev->agp_buffer_map) {
356 dev->dev_private = (void *)dev_priv; 352 dev->dev_private = (void *)dev_priv;
@@ -1383,3 +1379,19 @@ drm_ioctl_desc_t i810_ioctls[] = {
1383}; 1379};
1384 1380
1385int i810_max_ioctl = DRM_ARRAY_SIZE(i810_ioctls); 1381int i810_max_ioctl = DRM_ARRAY_SIZE(i810_ioctls);
1382
1383/**
1384 * Determine if the device really is AGP or not.
1385 *
1386 * All Intel graphics chipsets are treated as AGP, even if they are really
1387 * PCI-e.
1388 *
1389 * \param dev The device to be tested.
1390 *
1391 * \returns
1392 * A value of 1 is always retured to indictate every i810 is AGP.
1393 */
1394int i810_driver_device_is_agp(drm_device_t * dev)
1395{
1396 return 1;
1397}
diff --git a/drivers/char/drm/i810_drv.c b/drivers/char/drm/i810_drv.c
index ff51b3259af9..00609329d578 100644
--- a/drivers/char/drm/i810_drv.c
+++ b/drivers/char/drm/i810_drv.c
@@ -84,6 +84,7 @@ static struct drm_driver driver = {
84 .dev_priv_size = sizeof(drm_i810_buf_priv_t), 84 .dev_priv_size = sizeof(drm_i810_buf_priv_t),
85 .pretakedown = i810_driver_pretakedown, 85 .pretakedown = i810_driver_pretakedown,
86 .prerelease = i810_driver_prerelease, 86 .prerelease = i810_driver_prerelease,
87 .device_is_agp = i810_driver_device_is_agp,
87 .release = i810_driver_release, 88 .release = i810_driver_release,
88 .dma_quiescent = i810_driver_dma_quiescent, 89 .dma_quiescent = i810_driver_dma_quiescent,
89 .reclaim_buffers = i810_reclaim_buffers, 90 .reclaim_buffers = i810_reclaim_buffers,
diff --git a/drivers/char/drm/i810_drv.h b/drivers/char/drm/i810_drv.h
index 1b40538d1725..62ee4f58c59a 100644
--- a/drivers/char/drm/i810_drv.h
+++ b/drivers/char/drm/i810_drv.h
@@ -120,6 +120,7 @@ extern int i810_driver_dma_quiescent(drm_device_t *dev);
120extern void i810_driver_release(drm_device_t *dev, struct file *filp); 120extern void i810_driver_release(drm_device_t *dev, struct file *filp);
121extern void i810_driver_pretakedown(drm_device_t *dev); 121extern void i810_driver_pretakedown(drm_device_t *dev);
122extern void i810_driver_prerelease(drm_device_t *dev, DRMFILE filp); 122extern void i810_driver_prerelease(drm_device_t *dev, DRMFILE filp);
123extern int i810_driver_device_is_agp(drm_device_t * dev);
123 124
124#define I810_BASE(reg) ((unsigned long) \ 125#define I810_BASE(reg) ((unsigned long) \
125 dev_priv->mmio_map->handle) 126 dev_priv->mmio_map->handle)
diff --git a/drivers/char/drm/i830_dma.c b/drivers/char/drm/i830_dma.c
index dc7733035864..6f89d5796ef3 100644
--- a/drivers/char/drm/i830_dma.c
+++ b/drivers/char/drm/i830_dma.c
@@ -47,11 +47,6 @@
47#define I830_BUF_UNMAPPED 0 47#define I830_BUF_UNMAPPED 0
48#define I830_BUF_MAPPED 1 48#define I830_BUF_MAPPED 1
49 49
50#if LINUX_VERSION_CODE <= KERNEL_VERSION(2,4,2)
51#define down_write down
52#define up_write up
53#endif
54
55static drm_buf_t *i830_freelist_get(drm_device_t *dev) 50static drm_buf_t *i830_freelist_get(drm_device_t *dev)
56{ 51{
57 drm_device_dma_t *dma = dev->dma; 52 drm_device_dma_t *dma = dev->dma;
@@ -358,6 +353,7 @@ static int i830_dma_initialize(drm_device_t *dev,
358 DRM_ERROR("can not find mmio map!\n"); 353 DRM_ERROR("can not find mmio map!\n");
359 return -EINVAL; 354 return -EINVAL;
360 } 355 }
356 dev->agp_buffer_token = init->buffers_offset;
361 dev->agp_buffer_map = drm_core_findmap(dev, init->buffers_offset); 357 dev->agp_buffer_map = drm_core_findmap(dev, init->buffers_offset);
362 if(!dev->agp_buffer_map) { 358 if(!dev->agp_buffer_map) {
363 dev->dev_private = (void *)dev_priv; 359 dev->dev_private = (void *)dev_priv;
@@ -1586,3 +1582,19 @@ drm_ioctl_desc_t i830_ioctls[] = {
1586}; 1582};
1587 1583
1588int i830_max_ioctl = DRM_ARRAY_SIZE(i830_ioctls); 1584int i830_max_ioctl = DRM_ARRAY_SIZE(i830_ioctls);
1585
1586/**
1587 * Determine if the device really is AGP or not.
1588 *
1589 * All Intel graphics chipsets are treated as AGP, even if they are really
1590 * PCI-e.
1591 *
1592 * \param dev The device to be tested.
1593 *
1594 * \returns
1595 * A value of 1 is always retured to indictate every i8xx is AGP.
1596 */
1597int i830_driver_device_is_agp(drm_device_t * dev)
1598{
1599 return 1;
1600}
diff --git a/drivers/char/drm/i830_drv.c b/drivers/char/drm/i830_drv.c
index bc36be76b8b2..0da9cd19919e 100644
--- a/drivers/char/drm/i830_drv.c
+++ b/drivers/char/drm/i830_drv.c
@@ -88,6 +88,7 @@ static struct drm_driver driver = {
88 .dev_priv_size = sizeof(drm_i830_buf_priv_t), 88 .dev_priv_size = sizeof(drm_i830_buf_priv_t),
89 .pretakedown = i830_driver_pretakedown, 89 .pretakedown = i830_driver_pretakedown,
90 .prerelease = i830_driver_prerelease, 90 .prerelease = i830_driver_prerelease,
91 .device_is_agp = i830_driver_device_is_agp,
91 .release = i830_driver_release, 92 .release = i830_driver_release,
92 .dma_quiescent = i830_driver_dma_quiescent, 93 .dma_quiescent = i830_driver_dma_quiescent,
93 .reclaim_buffers = i830_reclaim_buffers, 94 .reclaim_buffers = i830_reclaim_buffers,
diff --git a/drivers/char/drm/i830_drv.h b/drivers/char/drm/i830_drv.h
index df7746131dea..63f96a8b6a4a 100644
--- a/drivers/char/drm/i830_drv.h
+++ b/drivers/char/drm/i830_drv.h
@@ -137,6 +137,7 @@ extern void i830_driver_pretakedown(drm_device_t *dev);
137extern void i830_driver_release(drm_device_t *dev, struct file *filp); 137extern void i830_driver_release(drm_device_t *dev, struct file *filp);
138extern int i830_driver_dma_quiescent(drm_device_t *dev); 138extern int i830_driver_dma_quiescent(drm_device_t *dev);
139extern void i830_driver_prerelease(drm_device_t *dev, DRMFILE filp); 139extern void i830_driver_prerelease(drm_device_t *dev, DRMFILE filp);
140extern int i830_driver_device_is_agp(drm_device_t * dev);
140 141
141#define I830_BASE(reg) ((unsigned long) \ 142#define I830_BASE(reg) ((unsigned long) \
142 dev_priv->mmio_map->handle) 143 dev_priv->mmio_map->handle)
diff --git a/drivers/char/drm/i915_dma.c b/drivers/char/drm/i915_dma.c
index acf9e52a9507..34f552f90c4a 100644
--- a/drivers/char/drm/i915_dma.c
+++ b/drivers/char/drm/i915_dma.c
@@ -95,9 +95,8 @@ static int i915_dma_cleanup(drm_device_t * dev)
95 drm_core_ioremapfree( &dev_priv->ring.map, dev); 95 drm_core_ioremapfree( &dev_priv->ring.map, dev);
96 } 96 }
97 97
98 if (dev_priv->hw_status_page) { 98 if (dev_priv->status_page_dmah) {
99 drm_pci_free(dev, PAGE_SIZE, dev_priv->hw_status_page, 99 drm_pci_free(dev, dev_priv->status_page_dmah);
100 dev_priv->dma_status_page);
101 /* Need to rewrite hardware status page */ 100 /* Need to rewrite hardware status page */
102 I915_WRITE(0x02080, 0x1ffff000); 101 I915_WRITE(0x02080, 0x1ffff000);
103 } 102 }
@@ -174,16 +173,18 @@ static int i915_initialize(drm_device_t * dev,
174 dev_priv->allow_batchbuffer = 1; 173 dev_priv->allow_batchbuffer = 1;
175 174
176 /* Program Hardware Status Page */ 175 /* Program Hardware Status Page */
177 dev_priv->hw_status_page = drm_pci_alloc(dev, PAGE_SIZE, PAGE_SIZE, 176 dev_priv->status_page_dmah = drm_pci_alloc(dev, PAGE_SIZE, PAGE_SIZE,
178 0xffffffff, 177 0xffffffff);
179 &dev_priv->dma_status_page);
180 178
181 if (!dev_priv->hw_status_page) { 179 if (!dev_priv->status_page_dmah) {
182 dev->dev_private = (void *)dev_priv; 180 dev->dev_private = (void *)dev_priv;
183 i915_dma_cleanup(dev); 181 i915_dma_cleanup(dev);
184 DRM_ERROR("Can not allocate hardware status page\n"); 182 DRM_ERROR("Can not allocate hardware status page\n");
185 return DRM_ERR(ENOMEM); 183 return DRM_ERR(ENOMEM);
186 } 184 }
185 dev_priv->hw_status_page = dev_priv->status_page_dmah->vaddr;
186 dev_priv->dma_status_page = dev_priv->status_page_dmah->busaddr;
187
187 memset(dev_priv->hw_status_page, 0, PAGE_SIZE); 188 memset(dev_priv->hw_status_page, 0, PAGE_SIZE);
188 DRM_DEBUG("hw status page @ %p\n", dev_priv->hw_status_page); 189 DRM_DEBUG("hw status page @ %p\n", dev_priv->hw_status_page);
189 190
@@ -731,3 +732,19 @@ drm_ioctl_desc_t i915_ioctls[] = {
731}; 732};
732 733
733int i915_max_ioctl = DRM_ARRAY_SIZE(i915_ioctls); 734int i915_max_ioctl = DRM_ARRAY_SIZE(i915_ioctls);
735
736/**
737 * Determine if the device really is AGP or not.
738 *
739 * All Intel graphics chipsets are treated as AGP, even if they are really
740 * PCI-e.
741 *
742 * \param dev The device to be tested.
743 *
744 * \returns
745 * A value of 1 is always retured to indictate every i9x5 is AGP.
746 */
747int i915_driver_device_is_agp(drm_device_t * dev)
748{
749 return 1;
750}
diff --git a/drivers/char/drm/i915_drv.c b/drivers/char/drm/i915_drv.c
index 1f59d3fc79bc..106b9ec02213 100644
--- a/drivers/char/drm/i915_drv.c
+++ b/drivers/char/drm/i915_drv.c
@@ -79,6 +79,7 @@ static struct drm_driver driver = {
79 DRIVER_HAVE_IRQ | DRIVER_IRQ_SHARED, 79 DRIVER_HAVE_IRQ | DRIVER_IRQ_SHARED,
80 .pretakedown = i915_driver_pretakedown, 80 .pretakedown = i915_driver_pretakedown,
81 .prerelease = i915_driver_prerelease, 81 .prerelease = i915_driver_prerelease,
82 .device_is_agp = i915_driver_device_is_agp,
82 .irq_preinstall = i915_driver_irq_preinstall, 83 .irq_preinstall = i915_driver_irq_preinstall,
83 .irq_postinstall = i915_driver_irq_postinstall, 84 .irq_postinstall = i915_driver_irq_postinstall,
84 .irq_uninstall = i915_driver_irq_uninstall, 85 .irq_uninstall = i915_driver_irq_uninstall,
diff --git a/drivers/char/drm/i915_drv.h b/drivers/char/drm/i915_drv.h
index 9c37d2367dd5..70ed4e68eac8 100644
--- a/drivers/char/drm/i915_drv.h
+++ b/drivers/char/drm/i915_drv.h
@@ -79,9 +79,10 @@ typedef struct drm_i915_private {
79 drm_i915_sarea_t *sarea_priv; 79 drm_i915_sarea_t *sarea_priv;
80 drm_i915_ring_buffer_t ring; 80 drm_i915_ring_buffer_t ring;
81 81
82 drm_dma_handle_t *status_page_dmah;
82 void *hw_status_page; 83 void *hw_status_page;
83 unsigned long counter;
84 dma_addr_t dma_status_page; 84 dma_addr_t dma_status_page;
85 unsigned long counter;
85 86
86 int back_offset; 87 int back_offset;
87 int front_offset; 88 int front_offset;
@@ -102,6 +103,7 @@ typedef struct drm_i915_private {
102extern void i915_kernel_lost_context(drm_device_t * dev); 103extern void i915_kernel_lost_context(drm_device_t * dev);
103extern void i915_driver_pretakedown(drm_device_t *dev); 104extern void i915_driver_pretakedown(drm_device_t *dev);
104extern void i915_driver_prerelease(drm_device_t *dev, DRMFILE filp); 105extern void i915_driver_prerelease(drm_device_t *dev, DRMFILE filp);
106extern int i915_driver_device_is_agp(drm_device_t *dev);
105 107
106/* i915_irq.c */ 108/* i915_irq.c */
107extern int i915_irq_emit(DRM_IOCTL_ARGS); 109extern int i915_irq_emit(DRM_IOCTL_ARGS);
diff --git a/drivers/char/drm/mga_dma.c b/drivers/char/drm/mga_dma.c
index 832eaf8a5068..567b425b784f 100644
--- a/drivers/char/drm/mga_dma.c
+++ b/drivers/char/drm/mga_dma.c
@@ -23,18 +23,21 @@
23 * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, 23 * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
24 * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER 24 * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
25 * DEALINGS IN THE SOFTWARE. 25 * DEALINGS IN THE SOFTWARE.
26 * 26 */
27 * Authors: 27
28 * Rickard E. (Rik) Faith <faith@valinux.com> 28/**
29 * Jeff Hartmann <jhartmann@valinux.com> 29 * \file mga_dma.c
30 * Keith Whitwell <keith@tungstengraphics.com> 30 * DMA support for MGA G200 / G400.
31 * 31 *
32 * Rewritten by: 32 * \author Rickard E. (Rik) Faith <faith@valinux.com>
33 * Gareth Hughes <gareth@valinux.com> 33 * \author Jeff Hartmann <jhartmann@valinux.com>
34 * \author Keith Whitwell <keith@tungstengraphics.com>
35 * \author Gareth Hughes <gareth@valinux.com>
34 */ 36 */
35 37
36#include "drmP.h" 38#include "drmP.h"
37#include "drm.h" 39#include "drm.h"
40#include "drm_sarea.h"
38#include "mga_drm.h" 41#include "mga_drm.h"
39#include "mga_drv.h" 42#include "mga_drv.h"
40 43
@@ -148,7 +151,7 @@ void mga_do_dma_flush( drm_mga_private_t *dev_priv )
148 DRM_DEBUG( " space = 0x%06x\n", primary->space ); 151 DRM_DEBUG( " space = 0x%06x\n", primary->space );
149 152
150 mga_flush_write_combine(); 153 mga_flush_write_combine();
151 MGA_WRITE( MGA_PRIMEND, tail | MGA_PAGPXFER ); 154 MGA_WRITE(MGA_PRIMEND, tail | dev_priv->dma_access);
152 155
153 DRM_DEBUG( "done.\n" ); 156 DRM_DEBUG( "done.\n" );
154} 157}
@@ -190,7 +193,7 @@ void mga_do_dma_wrap_start( drm_mga_private_t *dev_priv )
190 DRM_DEBUG( " space = 0x%06x\n", primary->space ); 193 DRM_DEBUG( " space = 0x%06x\n", primary->space );
191 194
192 mga_flush_write_combine(); 195 mga_flush_write_combine();
193 MGA_WRITE( MGA_PRIMEND, tail | MGA_PAGPXFER ); 196 MGA_WRITE(MGA_PRIMEND, tail | dev_priv->dma_access);
194 197
195 set_bit( 0, &primary->wrapped ); 198 set_bit( 0, &primary->wrapped );
196 DRM_DEBUG( "done.\n" ); 199 DRM_DEBUG( "done.\n" );
@@ -396,23 +399,383 @@ int mga_freelist_put( drm_device_t *dev, drm_buf_t *buf )
396 * DMA initialization, cleanup 399 * DMA initialization, cleanup
397 */ 400 */
398 401
402
403int mga_driver_preinit(drm_device_t *dev, unsigned long flags)
404{
405 drm_mga_private_t * dev_priv;
406
407 dev_priv = drm_alloc(sizeof(drm_mga_private_t), DRM_MEM_DRIVER);
408 if (!dev_priv)
409 return DRM_ERR(ENOMEM);
410
411 dev->dev_private = (void *)dev_priv;
412 memset(dev_priv, 0, sizeof(drm_mga_private_t));
413
414 dev_priv->usec_timeout = MGA_DEFAULT_USEC_TIMEOUT;
415 dev_priv->chipset = flags;
416
417 return 0;
418}
419
420/**
421 * Bootstrap the driver for AGP DMA.
422 *
423 * \todo
424 * Investigate whether there is any benifit to storing the WARP microcode in
425 * AGP memory. If not, the microcode may as well always be put in PCI
426 * memory.
427 *
428 * \todo
429 * This routine needs to set dma_bs->agp_mode to the mode actually configured
430 * in the hardware. Looking just at the Linux AGP driver code, I don't see
431 * an easy way to determine this.
432 *
433 * \sa mga_do_dma_bootstrap, mga_do_pci_dma_bootstrap
434 */
435static int mga_do_agp_dma_bootstrap(drm_device_t * dev,
436 drm_mga_dma_bootstrap_t * dma_bs)
437{
438 drm_mga_private_t * const dev_priv = (drm_mga_private_t *) dev->dev_private;
439 const unsigned int warp_size = mga_warp_microcode_size(dev_priv);
440 int err;
441 unsigned offset;
442 const unsigned secondary_size = dma_bs->secondary_bin_count
443 * dma_bs->secondary_bin_size;
444 const unsigned agp_size = (dma_bs->agp_size << 20);
445 drm_buf_desc_t req;
446 drm_agp_mode_t mode;
447 drm_agp_info_t info;
448
449
450 /* Acquire AGP. */
451 err = drm_agp_acquire(dev);
452 if (err) {
453 DRM_ERROR("Unable to acquire AGP\n");
454 return err;
455 }
456
457 err = drm_agp_info(dev, &info);
458 if (err) {
459 DRM_ERROR("Unable to get AGP info\n");
460 return err;
461 }
462
463 mode.mode = (info.mode & ~0x07) | dma_bs->agp_mode;
464 err = drm_agp_enable(dev, mode);
465 if (err) {
466 DRM_ERROR("Unable to enable AGP (mode = 0x%lx)\n", mode.mode);
467 return err;
468 }
469
470
471 /* In addition to the usual AGP mode configuration, the G200 AGP cards
472 * need to have the AGP mode "manually" set.
473 */
474
475 if (dev_priv->chipset == MGA_CARD_TYPE_G200) {
476 if (mode.mode & 0x02) {
477 MGA_WRITE(MGA_AGP_PLL, MGA_AGP2XPLL_ENABLE);
478 }
479 else {
480 MGA_WRITE(MGA_AGP_PLL, MGA_AGP2XPLL_DISABLE);
481 }
482 }
483
484
485 /* Allocate and bind AGP memory. */
486 dev_priv->agp_pages = agp_size / PAGE_SIZE;
487 dev_priv->agp_mem = drm_alloc_agp( dev, dev_priv->agp_pages, 0 );
488 if (dev_priv->agp_mem == NULL) {
489 dev_priv->agp_pages = 0;
490 DRM_ERROR("Unable to allocate %uMB AGP memory\n",
491 dma_bs->agp_size);
492 return DRM_ERR(ENOMEM);
493 }
494
495 err = drm_bind_agp( dev_priv->agp_mem, 0 );
496 if (err) {
497 DRM_ERROR("Unable to bind AGP memory\n");
498 return err;
499 }
500
501 offset = 0;
502 err = drm_addmap( dev, offset, warp_size,
503 _DRM_AGP, _DRM_READ_ONLY, & dev_priv->warp );
504 if (err) {
505 DRM_ERROR("Unable to map WARP microcode\n");
506 return err;
507 }
508
509 offset += warp_size;
510 err = drm_addmap( dev, offset, dma_bs->primary_size,
511 _DRM_AGP, _DRM_READ_ONLY, & dev_priv->primary );
512 if (err) {
513 DRM_ERROR("Unable to map primary DMA region\n");
514 return err;
515 }
516
517 offset += dma_bs->primary_size;
518 err = drm_addmap( dev, offset, secondary_size,
519 _DRM_AGP, 0, & dev->agp_buffer_map );
520 if (err) {
521 DRM_ERROR("Unable to map secondary DMA region\n");
522 return err;
523 }
524
525 (void) memset( &req, 0, sizeof(req) );
526 req.count = dma_bs->secondary_bin_count;
527 req.size = dma_bs->secondary_bin_size;
528 req.flags = _DRM_AGP_BUFFER;
529 req.agp_start = offset;
530
531 err = drm_addbufs_agp( dev, & req );
532 if (err) {
533 DRM_ERROR("Unable to add secondary DMA buffers\n");
534 return err;
535 }
536
537 offset += secondary_size;
538 err = drm_addmap( dev, offset, agp_size - offset,
539 _DRM_AGP, 0, & dev_priv->agp_textures );
540 if (err) {
541 DRM_ERROR("Unable to map AGP texture region\n");
542 return err;
543 }
544
545 drm_core_ioremap(dev_priv->warp, dev);
546 drm_core_ioremap(dev_priv->primary, dev);
547 drm_core_ioremap(dev->agp_buffer_map, dev);
548
549 if (!dev_priv->warp->handle ||
550 !dev_priv->primary->handle || !dev->agp_buffer_map->handle) {
551 DRM_ERROR("failed to ioremap agp regions! (%p, %p, %p)\n",
552 dev_priv->warp->handle, dev_priv->primary->handle,
553 dev->agp_buffer_map->handle);
554 return DRM_ERR(ENOMEM);
555 }
556
557 dev_priv->dma_access = MGA_PAGPXFER;
558 dev_priv->wagp_enable = MGA_WAGP_ENABLE;
559
560 DRM_INFO("Initialized card for AGP DMA.\n");
561 return 0;
562}
563
564/**
565 * Bootstrap the driver for PCI DMA.
566 *
567 * \todo
568 * The algorithm for decreasing the size of the primary DMA buffer could be
569 * better. The size should be rounded up to the nearest page size, then
570 * decrease the request size by a single page each pass through the loop.
571 *
572 * \todo
573 * Determine whether the maximum address passed to drm_pci_alloc is correct.
574 * The same goes for drm_addbufs_pci.
575 *
576 * \sa mga_do_dma_bootstrap, mga_do_agp_dma_bootstrap
577 */
578static int mga_do_pci_dma_bootstrap(drm_device_t * dev,
579 drm_mga_dma_bootstrap_t * dma_bs)
580{
581 drm_mga_private_t * const dev_priv = (drm_mga_private_t *) dev->dev_private;
582 const unsigned int warp_size = mga_warp_microcode_size(dev_priv);
583 unsigned int primary_size;
584 unsigned int bin_count;
585 int err;
586 drm_buf_desc_t req;
587
588
589 if (dev->dma == NULL) {
590 DRM_ERROR("dev->dma is NULL\n");
591 return DRM_ERR(EFAULT);
592 }
593
594 /* The proper alignment is 0x100 for this mapping */
595 err = drm_addmap(dev, 0, warp_size, _DRM_CONSISTENT,
596 _DRM_READ_ONLY, &dev_priv->warp);
597 if (err != 0) {
598 DRM_ERROR("Unable to create mapping for WARP microcode\n");
599 return err;
600 }
601
602 /* Other than the bottom two bits being used to encode other
603 * information, there don't appear to be any restrictions on the
604 * alignment of the primary or secondary DMA buffers.
605 */
606
607 for ( primary_size = dma_bs->primary_size
608 ; primary_size != 0
609 ; primary_size >>= 1 ) {
610 /* The proper alignment for this mapping is 0x04 */
611 err = drm_addmap(dev, 0, primary_size, _DRM_CONSISTENT,
612 _DRM_READ_ONLY, &dev_priv->primary);
613 if (!err)
614 break;
615 }
616
617 if (err != 0) {
618 DRM_ERROR("Unable to allocate primary DMA region\n");
619 return DRM_ERR(ENOMEM);
620 }
621
622 if (dev_priv->primary->size != dma_bs->primary_size) {
623 DRM_INFO("Primary DMA buffer size reduced from %u to %u.\n",
624 dma_bs->primary_size,
625 (unsigned) dev_priv->primary->size);
626 dma_bs->primary_size = dev_priv->primary->size;
627 }
628
629 for ( bin_count = dma_bs->secondary_bin_count
630 ; bin_count > 0
631 ; bin_count-- ) {
632 (void) memset( &req, 0, sizeof(req) );
633 req.count = bin_count;
634 req.size = dma_bs->secondary_bin_size;
635
636 err = drm_addbufs_pci( dev, & req );
637 if (!err) {
638 break;
639 }
640 }
641
642 if (bin_count == 0) {
643 DRM_ERROR("Unable to add secondary DMA buffers\n");
644 return err;
645 }
646
647 if (bin_count != dma_bs->secondary_bin_count) {
648 DRM_INFO("Secondary PCI DMA buffer bin count reduced from %u "
649 "to %u.\n", dma_bs->secondary_bin_count, bin_count);
650
651 dma_bs->secondary_bin_count = bin_count;
652 }
653
654 dev_priv->dma_access = 0;
655 dev_priv->wagp_enable = 0;
656
657 dma_bs->agp_mode = 0;
658
659 DRM_INFO("Initialized card for PCI DMA.\n");
660 return 0;
661}
662
663
664static int mga_do_dma_bootstrap(drm_device_t * dev,
665 drm_mga_dma_bootstrap_t * dma_bs)
666{
667 const int is_agp = (dma_bs->agp_mode != 0) && drm_device_is_agp(dev);
668 int err;
669 drm_mga_private_t * const dev_priv =
670 (drm_mga_private_t *) dev->dev_private;
671
672
673 dev_priv->used_new_dma_init = 1;
674
675 /* The first steps are the same for both PCI and AGP based DMA. Map
676 * the cards MMIO registers and map a status page.
677 */
678 err = drm_addmap( dev, dev_priv->mmio_base, dev_priv->mmio_size,
679 _DRM_REGISTERS, _DRM_READ_ONLY, & dev_priv->mmio );
680 if (err) {
681 DRM_ERROR("Unable to map MMIO region\n");
682 return err;
683 }
684
685
686 err = drm_addmap( dev, 0, SAREA_MAX, _DRM_SHM,
687 _DRM_READ_ONLY | _DRM_LOCKED | _DRM_KERNEL,
688 & dev_priv->status );
689 if (err) {
690 DRM_ERROR("Unable to map status region\n");
691 return err;
692 }
693
694
695 /* The DMA initialization procedure is slightly different for PCI and
696 * AGP cards. AGP cards just allocate a large block of AGP memory and
697 * carve off portions of it for internal uses. The remaining memory
698 * is returned to user-mode to be used for AGP textures.
699 */
700
701 if (is_agp) {
702 err = mga_do_agp_dma_bootstrap(dev, dma_bs);
703 }
704
705 /* If we attempted to initialize the card for AGP DMA but failed,
706 * clean-up any mess that may have been created.
707 */
708
709 if (err) {
710 mga_do_cleanup_dma(dev);
711 }
712
713
714 /* Not only do we want to try and initialized PCI cards for PCI DMA,
715 * but we also try to initialized AGP cards that could not be
716 * initialized for AGP DMA. This covers the case where we have an AGP
717 * card in a system with an unsupported AGP chipset. In that case the
718 * card will be detected as AGP, but we won't be able to allocate any
719 * AGP memory, etc.
720 */
721
722 if (!is_agp || err) {
723 err = mga_do_pci_dma_bootstrap(dev, dma_bs);
724 }
725
726
727 return err;
728}
729
730int mga_dma_bootstrap(DRM_IOCTL_ARGS)
731{
732 DRM_DEVICE;
733 drm_mga_dma_bootstrap_t bootstrap;
734 int err;
735
736
737 DRM_COPY_FROM_USER_IOCTL(bootstrap,
738 (drm_mga_dma_bootstrap_t __user *) data,
739 sizeof(bootstrap));
740
741 err = mga_do_dma_bootstrap(dev, & bootstrap);
742 if (! err) {
743 static const int modes[] = { 0, 1, 2, 2, 4, 4, 4, 4 };
744 const drm_mga_private_t * const dev_priv =
745 (drm_mga_private_t *) dev->dev_private;
746
747 if (dev_priv->agp_textures != NULL) {
748 bootstrap.texture_handle = dev_priv->agp_textures->offset;
749 bootstrap.texture_size = dev_priv->agp_textures->size;
750 }
751 else {
752 bootstrap.texture_handle = 0;
753 bootstrap.texture_size = 0;
754 }
755
756 bootstrap.agp_mode = modes[ bootstrap.agp_mode & 0x07 ];
757 if (DRM_COPY_TO_USER( (void __user *) data, & bootstrap,
758 sizeof(bootstrap))) {
759 err = DRM_ERR(EFAULT);
760 }
761 }
762 else {
763 mga_do_cleanup_dma(dev);
764 }
765
766 return err;
767}
768
399static int mga_do_init_dma( drm_device_t *dev, drm_mga_init_t *init ) 769static int mga_do_init_dma( drm_device_t *dev, drm_mga_init_t *init )
400{ 770{
401 drm_mga_private_t *dev_priv; 771 drm_mga_private_t *dev_priv;
402 int ret; 772 int ret;
403 DRM_DEBUG( "\n" ); 773 DRM_DEBUG( "\n" );
404 774
405 dev_priv = drm_alloc( sizeof(drm_mga_private_t), DRM_MEM_DRIVER );
406 if ( !dev_priv )
407 return DRM_ERR(ENOMEM);
408
409 memset( dev_priv, 0, sizeof(drm_mga_private_t) );
410 775
411 dev_priv->chipset = init->chipset; 776 dev_priv = dev->dev_private;
412 777
413 dev_priv->usec_timeout = MGA_DEFAULT_USEC_TIMEOUT; 778 if (init->sgram) {
414
415 if ( init->sgram ) {
416 dev_priv->clear_cmd = MGA_DWGCTL_CLEAR | MGA_ATYPE_BLK; 779 dev_priv->clear_cmd = MGA_DWGCTL_CLEAR | MGA_ATYPE_BLK;
417 } else { 780 } else {
418 dev_priv->clear_cmd = MGA_DWGCTL_CLEAR | MGA_ATYPE_RSTR; 781 dev_priv->clear_cmd = MGA_DWGCTL_CLEAR | MGA_ATYPE_RSTR;
@@ -436,88 +799,66 @@ static int mga_do_init_dma( drm_device_t *dev, drm_mga_init_t *init )
436 799
437 DRM_GETSAREA(); 800 DRM_GETSAREA();
438 801
439 if(!dev_priv->sarea) { 802 if (!dev_priv->sarea) {
440 DRM_ERROR( "failed to find sarea!\n" ); 803 DRM_ERROR("failed to find sarea!\n");
441 /* Assign dev_private so we can do cleanup. */
442 dev->dev_private = (void *)dev_priv;
443 mga_do_cleanup_dma( dev );
444 return DRM_ERR(EINVAL); 804 return DRM_ERR(EINVAL);
445 } 805 }
446 806
447 dev_priv->mmio = drm_core_findmap(dev, init->mmio_offset); 807 if (! dev_priv->used_new_dma_init) {
448 if(!dev_priv->mmio) { 808 dev_priv->status = drm_core_findmap(dev, init->status_offset);
449 DRM_ERROR( "failed to find mmio region!\n" ); 809 if (!dev_priv->status) {
450 /* Assign dev_private so we can do cleanup. */ 810 DRM_ERROR("failed to find status page!\n");
451 dev->dev_private = (void *)dev_priv; 811 return DRM_ERR(EINVAL);
452 mga_do_cleanup_dma( dev ); 812 }
453 return DRM_ERR(EINVAL); 813 dev_priv->mmio = drm_core_findmap(dev, init->mmio_offset);
454 } 814 if (!dev_priv->mmio) {
455 dev_priv->status = drm_core_findmap(dev, init->status_offset); 815 DRM_ERROR("failed to find mmio region!\n");
456 if(!dev_priv->status) { 816 return DRM_ERR(EINVAL);
457 DRM_ERROR( "failed to find status page!\n" ); 817 }
458 /* Assign dev_private so we can do cleanup. */ 818 dev_priv->warp = drm_core_findmap(dev, init->warp_offset);
459 dev->dev_private = (void *)dev_priv; 819 if (!dev_priv->warp) {
460 mga_do_cleanup_dma( dev ); 820 DRM_ERROR("failed to find warp microcode region!\n");
461 return DRM_ERR(EINVAL); 821 return DRM_ERR(EINVAL);
462 } 822 }
463 dev_priv->warp = drm_core_findmap(dev, init->warp_offset); 823 dev_priv->primary = drm_core_findmap(dev, init->primary_offset);
464 if(!dev_priv->warp) { 824 if (!dev_priv->primary) {
465 DRM_ERROR( "failed to find warp microcode region!\n" ); 825 DRM_ERROR("failed to find primary dma region!\n");
466 /* Assign dev_private so we can do cleanup. */ 826 return DRM_ERR(EINVAL);
467 dev->dev_private = (void *)dev_priv; 827 }
468 mga_do_cleanup_dma( dev ); 828 dev->agp_buffer_token = init->buffers_offset;
469 return DRM_ERR(EINVAL); 829 dev->agp_buffer_map = drm_core_findmap(dev, init->buffers_offset);
470 } 830 if (!dev->agp_buffer_map) {
471 dev_priv->primary = drm_core_findmap(dev, init->primary_offset); 831 DRM_ERROR("failed to find dma buffer region!\n");
472 if(!dev_priv->primary) { 832 return DRM_ERR(EINVAL);
473 DRM_ERROR( "failed to find primary dma region!\n" ); 833 }
474 /* Assign dev_private so we can do cleanup. */ 834
475 dev->dev_private = (void *)dev_priv; 835 drm_core_ioremap(dev_priv->warp, dev);
476 mga_do_cleanup_dma( dev ); 836 drm_core_ioremap(dev_priv->primary, dev);
477 return DRM_ERR(EINVAL); 837 drm_core_ioremap(dev->agp_buffer_map, dev);
478 }
479 dev->agp_buffer_map = drm_core_findmap(dev, init->buffers_offset);
480 if(!dev->agp_buffer_map) {
481 DRM_ERROR( "failed to find dma buffer region!\n" );
482 /* Assign dev_private so we can do cleanup. */
483 dev->dev_private = (void *)dev_priv;
484 mga_do_cleanup_dma( dev );
485 return DRM_ERR(EINVAL);
486 } 838 }
487 839
488 dev_priv->sarea_priv = 840 dev_priv->sarea_priv =
489 (drm_mga_sarea_t *)((u8 *)dev_priv->sarea->handle + 841 (drm_mga_sarea_t *)((u8 *)dev_priv->sarea->handle +
490 init->sarea_priv_offset); 842 init->sarea_priv_offset);
491 843
492 drm_core_ioremap( dev_priv->warp, dev ); 844 if (!dev_priv->warp->handle ||
493 drm_core_ioremap( dev_priv->primary, dev ); 845 !dev_priv->primary->handle ||
494 drm_core_ioremap( dev->agp_buffer_map, dev ); 846 ((dev_priv->dma_access != 0) &&
495 847 ((dev->agp_buffer_map == NULL) ||
496 if(!dev_priv->warp->handle || 848 (dev->agp_buffer_map->handle == NULL)))) {
497 !dev_priv->primary->handle || 849 DRM_ERROR("failed to ioremap agp regions!\n");
498 !dev->agp_buffer_map->handle ) {
499 DRM_ERROR( "failed to ioremap agp regions!\n" );
500 /* Assign dev_private so we can do cleanup. */
501 dev->dev_private = (void *)dev_priv;
502 mga_do_cleanup_dma( dev );
503 return DRM_ERR(ENOMEM); 850 return DRM_ERR(ENOMEM);
504 } 851 }
505 852
506 ret = mga_warp_install_microcode( dev_priv ); 853 ret = mga_warp_install_microcode(dev_priv);
507 if ( ret < 0 ) { 854 if (ret < 0) {
508 DRM_ERROR( "failed to install WARP ucode!\n" ); 855 DRM_ERROR("failed to install WARP ucode!\n");
509 /* Assign dev_private so we can do cleanup. */
510 dev->dev_private = (void *)dev_priv;
511 mga_do_cleanup_dma( dev );
512 return ret; 856 return ret;
513 } 857 }
514 858
515 ret = mga_warp_init( dev_priv ); 859 ret = mga_warp_init(dev_priv);
516 if ( ret < 0 ) { 860 if (ret < 0) {
517 DRM_ERROR( "failed to init WARP engine!\n" ); 861 DRM_ERROR("failed to init WARP engine!\n");
518 /* Assign dev_private so we can do cleanup. */
519 dev->dev_private = (void *)dev_priv;
520 mga_do_cleanup_dma( dev );
521 return ret; 862 return ret;
522 } 863 }
523 864
@@ -557,22 +898,18 @@ static int mga_do_init_dma( drm_device_t *dev, drm_mga_init_t *init )
557 dev_priv->sarea_priv->last_frame.head = 0; 898 dev_priv->sarea_priv->last_frame.head = 0;
558 dev_priv->sarea_priv->last_frame.wrap = 0; 899 dev_priv->sarea_priv->last_frame.wrap = 0;
559 900
560 if ( mga_freelist_init( dev, dev_priv ) < 0 ) { 901 if (mga_freelist_init(dev, dev_priv) < 0) {
561 DRM_ERROR( "could not initialize freelist\n" ); 902 DRM_ERROR("could not initialize freelist\n");
562 /* Assign dev_private so we can do cleanup. */
563 dev->dev_private = (void *)dev_priv;
564 mga_do_cleanup_dma( dev );
565 return DRM_ERR(ENOMEM); 903 return DRM_ERR(ENOMEM);
566 } 904 }
567 905
568 /* Make dev_private visable to others. */
569 dev->dev_private = (void *)dev_priv;
570 return 0; 906 return 0;
571} 907}
572 908
573static int mga_do_cleanup_dma( drm_device_t *dev ) 909static int mga_do_cleanup_dma( drm_device_t *dev )
574{ 910{
575 DRM_DEBUG( "\n" ); 911 int err = 0;
912 DRM_DEBUG("\n");
576 913
577 /* Make sure interrupts are disabled here because the uninstall ioctl 914 /* Make sure interrupts are disabled here because the uninstall ioctl
578 * may not have been called from userspace and after dev_private 915 * may not have been called from userspace and after dev_private
@@ -583,20 +920,49 @@ static int mga_do_cleanup_dma( drm_device_t *dev )
583 if ( dev->dev_private ) { 920 if ( dev->dev_private ) {
584 drm_mga_private_t *dev_priv = dev->dev_private; 921 drm_mga_private_t *dev_priv = dev->dev_private;
585 922
586 if ( dev_priv->warp != NULL ) 923 if ((dev_priv->warp != NULL)
587 drm_core_ioremapfree( dev_priv->warp, dev ); 924 && (dev_priv->mmio->type != _DRM_CONSISTENT))
588 if ( dev_priv->primary != NULL ) 925 drm_core_ioremapfree(dev_priv->warp, dev);
589 drm_core_ioremapfree( dev_priv->primary, dev ); 926
590 if ( dev->agp_buffer_map != NULL ) 927 if ((dev_priv->primary != NULL)
591 drm_core_ioremapfree( dev->agp_buffer_map, dev ); 928 && (dev_priv->primary->type != _DRM_CONSISTENT))
929 drm_core_ioremapfree(dev_priv->primary, dev);
592 930
593 if ( dev_priv->head != NULL ) { 931 if (dev->agp_buffer_map != NULL)
594 mga_freelist_cleanup( dev ); 932 drm_core_ioremapfree(dev->agp_buffer_map, dev);
933
934 if (dev_priv->used_new_dma_init) {
935 if (dev_priv->agp_mem != NULL) {
936 dev_priv->agp_textures = NULL;
937 drm_unbind_agp(dev_priv->agp_mem);
938
939 drm_free_agp(dev_priv->agp_mem, dev_priv->agp_pages);
940 dev_priv->agp_pages = 0;
941 dev_priv->agp_mem = NULL;
942 }
943
944 if ((dev->agp != NULL) && dev->agp->acquired) {
945 err = drm_agp_release(dev);
946 }
947
948 dev_priv->used_new_dma_init = 0;
595 } 949 }
596 950
597 drm_free( dev->dev_private, sizeof(drm_mga_private_t), 951 dev_priv->warp = NULL;
598 DRM_MEM_DRIVER ); 952 dev_priv->primary = NULL;
599 dev->dev_private = NULL; 953 dev_priv->mmio = NULL;
954 dev_priv->status = NULL;
955 dev_priv->sarea = NULL;
956 dev_priv->sarea_priv = NULL;
957 dev->agp_buffer_map = NULL;
958
959 memset(&dev_priv->prim, 0, sizeof(dev_priv->prim));
960 dev_priv->warp_pipe = 0;
961 memset(dev_priv->warp_pipe_phys, 0, sizeof(dev_priv->warp_pipe_phys));
962
963 if (dev_priv->head != NULL) {
964 mga_freelist_cleanup(dev);
965 }
600 } 966 }
601 967
602 return 0; 968 return 0;
@@ -606,14 +972,20 @@ int mga_dma_init( DRM_IOCTL_ARGS )
606{ 972{
607 DRM_DEVICE; 973 DRM_DEVICE;
608 drm_mga_init_t init; 974 drm_mga_init_t init;
975 int err;
609 976
610 LOCK_TEST_WITH_RETURN( dev, filp ); 977 LOCK_TEST_WITH_RETURN( dev, filp );
611 978
612 DRM_COPY_FROM_USER_IOCTL( init, (drm_mga_init_t __user *)data, sizeof(init) ); 979 DRM_COPY_FROM_USER_IOCTL(init, (drm_mga_init_t __user *) data,
980 sizeof(init));
613 981
614 switch ( init.func ) { 982 switch ( init.func ) {
615 case MGA_INIT_DMA: 983 case MGA_INIT_DMA:
616 return mga_do_init_dma( dev, &init ); 984 err = mga_do_init_dma(dev, &init);
985 if (err) {
986 (void) mga_do_cleanup_dma(dev);
987 }
988 return err;
617 case MGA_CLEANUP_DMA: 989 case MGA_CLEANUP_DMA:
618 return mga_do_cleanup_dma( dev ); 990 return mga_do_cleanup_dma( dev );
619 } 991 }
@@ -742,7 +1114,21 @@ int mga_dma_buffers( DRM_IOCTL_ARGS )
742 return ret; 1114 return ret;
743} 1115}
744 1116
745void mga_driver_pretakedown(drm_device_t *dev) 1117/**
1118 * Called just before the module is unloaded.
1119 */
1120int mga_driver_postcleanup(drm_device_t * dev)
1121{
1122 drm_free(dev->dev_private, sizeof(drm_mga_private_t), DRM_MEM_DRIVER);
1123 dev->dev_private = NULL;
1124
1125 return 0;
1126}
1127
1128/**
1129 * Called when the last opener of the device is closed.
1130 */
1131void mga_driver_pretakedown(drm_device_t * dev)
746{ 1132{
747 mga_do_cleanup_dma( dev ); 1133 mga_do_cleanup_dma( dev );
748} 1134}
diff --git a/drivers/char/drm/mga_drm.h b/drivers/char/drm/mga_drm.h
index 521d4451d012..d20aab3bd57b 100644
--- a/drivers/char/drm/mga_drm.h
+++ b/drivers/char/drm/mga_drm.h
@@ -73,7 +73,8 @@
73 73
74#define MGA_CARD_TYPE_G200 1 74#define MGA_CARD_TYPE_G200 1
75#define MGA_CARD_TYPE_G400 2 75#define MGA_CARD_TYPE_G400 2
76 76#define MGA_CARD_TYPE_G450 3 /* not currently used */
77#define MGA_CARD_TYPE_G550 4
77 78
78#define MGA_FRONT 0x1 79#define MGA_FRONT 0x1
79#define MGA_BACK 0x2 80#define MGA_BACK 0x2
@@ -225,10 +226,6 @@ typedef struct _drm_mga_sarea {
225} drm_mga_sarea_t; 226} drm_mga_sarea_t;
226 227
227 228
228/* WARNING: If you change any of these defines, make sure to change the
229 * defines in the Xserver file (xf86drmMga.h)
230 */
231
232/* MGA specific ioctls 229/* MGA specific ioctls
233 * The device specific ioctl range is 0x40 to 0x79. 230 * The device specific ioctl range is 0x40 to 0x79.
234 */ 231 */
@@ -243,6 +240,14 @@ typedef struct _drm_mga_sarea {
243#define DRM_MGA_BLIT 0x08 240#define DRM_MGA_BLIT 0x08
244#define DRM_MGA_GETPARAM 0x09 241#define DRM_MGA_GETPARAM 0x09
245 242
243/* 3.2:
244 * ioctls for operating on fences.
245 */
246#define DRM_MGA_SET_FENCE 0x0a
247#define DRM_MGA_WAIT_FENCE 0x0b
248#define DRM_MGA_DMA_BOOTSTRAP 0x0c
249
250
246#define DRM_IOCTL_MGA_INIT DRM_IOW( DRM_COMMAND_BASE + DRM_MGA_INIT, drm_mga_init_t) 251#define DRM_IOCTL_MGA_INIT DRM_IOW( DRM_COMMAND_BASE + DRM_MGA_INIT, drm_mga_init_t)
247#define DRM_IOCTL_MGA_FLUSH DRM_IOW( DRM_COMMAND_BASE + DRM_MGA_FLUSH, drm_lock_t) 252#define DRM_IOCTL_MGA_FLUSH DRM_IOW( DRM_COMMAND_BASE + DRM_MGA_FLUSH, drm_lock_t)
248#define DRM_IOCTL_MGA_RESET DRM_IO( DRM_COMMAND_BASE + DRM_MGA_RESET) 253#define DRM_IOCTL_MGA_RESET DRM_IO( DRM_COMMAND_BASE + DRM_MGA_RESET)
@@ -253,6 +258,9 @@ typedef struct _drm_mga_sarea {
253#define DRM_IOCTL_MGA_ILOAD DRM_IOW( DRM_COMMAND_BASE + DRM_MGA_ILOAD, drm_mga_iload_t) 258#define DRM_IOCTL_MGA_ILOAD DRM_IOW( DRM_COMMAND_BASE + DRM_MGA_ILOAD, drm_mga_iload_t)
254#define DRM_IOCTL_MGA_BLIT DRM_IOW( DRM_COMMAND_BASE + DRM_MGA_BLIT, drm_mga_blit_t) 259#define DRM_IOCTL_MGA_BLIT DRM_IOW( DRM_COMMAND_BASE + DRM_MGA_BLIT, drm_mga_blit_t)
255#define DRM_IOCTL_MGA_GETPARAM DRM_IOWR(DRM_COMMAND_BASE + DRM_MGA_GETPARAM, drm_mga_getparam_t) 260#define DRM_IOCTL_MGA_GETPARAM DRM_IOWR(DRM_COMMAND_BASE + DRM_MGA_GETPARAM, drm_mga_getparam_t)
261#define DRM_IOCTL_MGA_SET_FENCE DRM_IOW( DRM_COMMAND_BASE + DRM_MGA_SET_FENCE, uint32_t)
262#define DRM_IOCTL_MGA_WAIT_FENCE DRM_IOWR(DRM_COMMAND_BASE + DRM_MGA_WAIT_FENCE, uint32_t)
263#define DRM_IOCTL_MGA_DMA_BOOTSTRAP DRM_IOWR(DRM_COMMAND_BASE + DRM_MGA_DMA_BOOTSTRAP, drm_mga_dma_bootstrap_t)
256 264
257typedef struct _drm_mga_warp_index { 265typedef struct _drm_mga_warp_index {
258 int installed; 266 int installed;
@@ -291,12 +299,72 @@ typedef struct drm_mga_init {
291 unsigned long buffers_offset; 299 unsigned long buffers_offset;
292} drm_mga_init_t; 300} drm_mga_init_t;
293 301
294typedef struct drm_mga_fullscreen { 302typedef struct drm_mga_dma_bootstrap {
295 enum { 303 /**
296 MGA_INIT_FULLSCREEN = 0x01, 304 * \name AGP texture region
297 MGA_CLEANUP_FULLSCREEN = 0x02 305 *
298 } func; 306 * On return from the DRM_MGA_DMA_BOOTSTRAP ioctl, these fields will
299} drm_mga_fullscreen_t; 307 * be filled in with the actual AGP texture settings.
308 *
309 * \warning
310 * If these fields are non-zero, but dma_mga_dma_bootstrap::agp_mode
311 * is zero, it means that PCI memory (most likely through the use of
312 * an IOMMU) is being used for "AGP" textures.
313 */
314 /*@{*/
315 unsigned long texture_handle; /**< Handle used to map AGP textures. */
316 uint32_t texture_size; /**< Size of the AGP texture region. */
317 /*@}*/
318
319
320 /**
321 * Requested size of the primary DMA region.
322 *
323 * On return from the DRM_MGA_DMA_BOOTSTRAP ioctl, this field will be
324 * filled in with the actual AGP mode. If AGP was not available
325 */
326 uint32_t primary_size;
327
328
329 /**
330 * Requested number of secondary DMA buffers.
331 *
332 * On return from the DRM_MGA_DMA_BOOTSTRAP ioctl, this field will be
333 * filled in with the actual number of secondary DMA buffers
334 * allocated. Particularly when PCI DMA is used, this may be
335 * (subtantially) less than the number requested.
336 */
337 uint32_t secondary_bin_count;
338
339
340 /**
341 * Requested size of each secondary DMA buffer.
342 *
343 * While the kernel \b is free to reduce
344 * dma_mga_dma_bootstrap::secondary_bin_count, it is \b not allowed
345 * to reduce dma_mga_dma_bootstrap::secondary_bin_size.
346 */
347 uint32_t secondary_bin_size;
348
349
350 /**
351 * Bit-wise mask of AGPSTAT2_* values. Currently only \c AGPSTAT2_1X,
352 * \c AGPSTAT2_2X, and \c AGPSTAT2_4X are supported. If this value is
353 * zero, it means that PCI DMA should be used, even if AGP is
354 * possible.
355 *
356 * On return from the DRM_MGA_DMA_BOOTSTRAP ioctl, this field will be
357 * filled in with the actual AGP mode. If AGP was not available
358 * (i.e., PCI DMA was used), this value will be zero.
359 */
360 uint32_t agp_mode;
361
362
363 /**
364 * Desired AGP GART size, measured in megabytes.
365 */
366 uint8_t agp_size;
367} drm_mga_dma_bootstrap_t;
300 368
301typedef struct drm_mga_clear { 369typedef struct drm_mga_clear {
302 unsigned int flags; 370 unsigned int flags;
@@ -341,6 +409,14 @@ typedef struct _drm_mga_blit {
341 */ 409 */
342#define MGA_PARAM_IRQ_NR 1 410#define MGA_PARAM_IRQ_NR 1
343 411
412/* 3.2: Query the actual card type. The DDX only distinguishes between
413 * G200 chips and non-G200 chips, which it calls G400. It turns out that
414 * there are some very sublte differences between the G4x0 chips and the G550
415 * chips. Using this parameter query, a client-side driver can detect the
416 * difference between a G4x0 and a G550.
417 */
418#define MGA_PARAM_CARD_TYPE 2
419
344typedef struct drm_mga_getparam { 420typedef struct drm_mga_getparam {
345 int param; 421 int param;
346 void __user *value; 422 void __user *value;
diff --git a/drivers/char/drm/mga_drv.c b/drivers/char/drm/mga_drv.c
index 844cca9cb29d..daabbba3b297 100644
--- a/drivers/char/drm/mga_drv.c
+++ b/drivers/char/drm/mga_drv.c
@@ -38,8 +38,15 @@
38 38
39#include "drm_pciids.h" 39#include "drm_pciids.h"
40 40
41static int mga_driver_device_is_agp(drm_device_t * dev);
41static int postinit( struct drm_device *dev, unsigned long flags ) 42static int postinit( struct drm_device *dev, unsigned long flags )
42{ 43{
44 drm_mga_private_t * const dev_priv =
45 (drm_mga_private_t *) dev->dev_private;
46
47 dev_priv->mmio_base = pci_resource_start(dev->pdev, 1);
48 dev_priv->mmio_size = pci_resource_len(dev->pdev, 1);
49
43 dev->counters += 3; 50 dev->counters += 3;
44 dev->types[6] = _DRM_STAT_IRQ; 51 dev->types[6] = _DRM_STAT_IRQ;
45 dev->types[7] = _DRM_STAT_PRIMARY; 52 dev->types[7] = _DRM_STAT_PRIMARY;
@@ -79,8 +86,11 @@ extern int mga_max_ioctl;
79 86
80static struct drm_driver driver = { 87static struct drm_driver driver = {
81 .driver_features = DRIVER_USE_AGP | DRIVER_REQUIRE_AGP | DRIVER_USE_MTRR | DRIVER_HAVE_DMA | DRIVER_HAVE_IRQ | DRIVER_IRQ_SHARED | DRIVER_IRQ_VBL, 88 .driver_features = DRIVER_USE_AGP | DRIVER_REQUIRE_AGP | DRIVER_USE_MTRR | DRIVER_HAVE_DMA | DRIVER_HAVE_IRQ | DRIVER_IRQ_SHARED | DRIVER_IRQ_VBL,
89 .preinit = mga_driver_preinit,
90 .postcleanup = mga_driver_postcleanup,
82 .pretakedown = mga_driver_pretakedown, 91 .pretakedown = mga_driver_pretakedown,
83 .dma_quiescent = mga_driver_dma_quiescent, 92 .dma_quiescent = mga_driver_dma_quiescent,
93 .device_is_agp = mga_driver_device_is_agp,
84 .vblank_wait = mga_driver_vblank_wait, 94 .vblank_wait = mga_driver_vblank_wait,
85 .irq_preinstall = mga_driver_irq_preinstall, 95 .irq_preinstall = mga_driver_irq_preinstall,
86 .irq_postinstall = mga_driver_irq_postinstall, 96 .irq_postinstall = mga_driver_irq_postinstall,
@@ -128,3 +138,38 @@ module_exit(mga_exit);
128MODULE_AUTHOR( DRIVER_AUTHOR ); 138MODULE_AUTHOR( DRIVER_AUTHOR );
129MODULE_DESCRIPTION( DRIVER_DESC ); 139MODULE_DESCRIPTION( DRIVER_DESC );
130MODULE_LICENSE("GPL and additional rights"); 140MODULE_LICENSE("GPL and additional rights");
141
142/**
143 * Determine if the device really is AGP or not.
144 *
145 * In addition to the usual tests performed by \c drm_device_is_agp, this
146 * function detects PCI G450 cards that appear to the system exactly like
147 * AGP G450 cards.
148 *
149 * \param dev The device to be tested.
150 *
151 * \returns
152 * If the device is a PCI G450, zero is returned. Otherwise 2 is returned.
153 */
154int mga_driver_device_is_agp(drm_device_t * dev)
155{
156 const struct pci_dev * const pdev = dev->pdev;
157
158
159 /* There are PCI versions of the G450. These cards have the
160 * same PCI ID as the AGP G450, but have an additional PCI-to-PCI
161 * bridge chip. We detect these cards, which are not currently
162 * supported by this driver, by looking at the device ID of the
163 * bus the "card" is on. If vendor is 0x3388 (Hint Corp) and the
164 * device is 0x0021 (HB6 Universal PCI-PCI bridge), we reject the
165 * device.
166 */
167
168 if ( (pdev->device == 0x0525)
169 && (pdev->bus->self->vendor == 0x3388)
170 && (pdev->bus->self->device == 0x0021) ) {
171 return 0;
172 }
173
174 return 2;
175}
diff --git a/drivers/char/drm/mga_drv.h b/drivers/char/drm/mga_drv.h
index 9412e2816eb7..b22fdbd4f830 100644
--- a/drivers/char/drm/mga_drv.h
+++ b/drivers/char/drm/mga_drv.h
@@ -38,10 +38,10 @@
38 38
39#define DRIVER_NAME "mga" 39#define DRIVER_NAME "mga"
40#define DRIVER_DESC "Matrox G200/G400" 40#define DRIVER_DESC "Matrox G200/G400"
41#define DRIVER_DATE "20021029" 41#define DRIVER_DATE "20050607"
42 42
43#define DRIVER_MAJOR 3 43#define DRIVER_MAJOR 3
44#define DRIVER_MINOR 1 44#define DRIVER_MINOR 2
45#define DRIVER_PATCHLEVEL 0 45#define DRIVER_PATCHLEVEL 0
46 46
47typedef struct drm_mga_primary_buffer { 47typedef struct drm_mga_primary_buffer {
@@ -87,9 +87,43 @@ typedef struct drm_mga_private {
87 int chipset; 87 int chipset;
88 int usec_timeout; 88 int usec_timeout;
89 89
90 /**
91 * If set, the new DMA initialization sequence was used. This is
92 * primarilly used to select how the driver should uninitialized its
93 * internal DMA structures.
94 */
95 int used_new_dma_init;
96
97 /**
98 * If AGP memory is used for DMA buffers, this will be the value
99 * \c MGA_PAGPXFER. Otherwise, it will be zero (for a PCI transfer).
100 */
101 u32 dma_access;
102
103 /**
104 * If AGP memory is used for DMA buffers, this will be the value
105 * \c MGA_WAGP_ENABLE. Otherwise, it will be zero (for a PCI
106 * transfer).
107 */
108 u32 wagp_enable;
109
110 /**
111 * \name MMIO region parameters.
112 *
113 * \sa drm_mga_private_t::mmio
114 */
115 /*@{*/
116 u32 mmio_base; /**< Bus address of base of MMIO. */
117 u32 mmio_size; /**< Size of the MMIO region. */
118 /*@}*/
119
90 u32 clear_cmd; 120 u32 clear_cmd;
91 u32 maccess; 121 u32 maccess;
92 122
123 wait_queue_head_t fence_queue;
124 atomic_t last_fence_retired;
125 u32 next_fence_to_post;
126
93 unsigned int fb_cpp; 127 unsigned int fb_cpp;
94 unsigned int front_offset; 128 unsigned int front_offset;
95 unsigned int front_pitch; 129 unsigned int front_pitch;
@@ -108,35 +142,43 @@ typedef struct drm_mga_private {
108 drm_local_map_t *status; 142 drm_local_map_t *status;
109 drm_local_map_t *warp; 143 drm_local_map_t *warp;
110 drm_local_map_t *primary; 144 drm_local_map_t *primary;
111 drm_local_map_t *buffers;
112 drm_local_map_t *agp_textures; 145 drm_local_map_t *agp_textures;
146
147 DRM_AGP_MEM *agp_mem;
148 unsigned int agp_pages;
113} drm_mga_private_t; 149} drm_mga_private_t;
114 150
115 /* mga_dma.c */ 151 /* mga_dma.c */
116extern int mga_dma_init( DRM_IOCTL_ARGS ); 152extern int mga_driver_preinit(drm_device_t * dev, unsigned long flags);
117extern int mga_dma_flush( DRM_IOCTL_ARGS ); 153extern int mga_dma_bootstrap(DRM_IOCTL_ARGS);
118extern int mga_dma_reset( DRM_IOCTL_ARGS ); 154extern int mga_dma_init(DRM_IOCTL_ARGS);
119extern int mga_dma_buffers( DRM_IOCTL_ARGS ); 155extern int mga_dma_flush(DRM_IOCTL_ARGS);
120extern void mga_driver_pretakedown(drm_device_t *dev); 156extern int mga_dma_reset(DRM_IOCTL_ARGS);
121extern int mga_driver_dma_quiescent(drm_device_t *dev); 157extern int mga_dma_buffers(DRM_IOCTL_ARGS);
122 158extern int mga_driver_postcleanup(drm_device_t * dev);
123extern int mga_do_wait_for_idle( drm_mga_private_t *dev_priv ); 159extern void mga_driver_pretakedown(drm_device_t * dev);
124 160extern int mga_driver_dma_quiescent(drm_device_t * dev);
125extern void mga_do_dma_flush( drm_mga_private_t *dev_priv ); 161
126extern void mga_do_dma_wrap_start( drm_mga_private_t *dev_priv ); 162extern int mga_do_wait_for_idle(drm_mga_private_t * dev_priv);
127extern void mga_do_dma_wrap_end( drm_mga_private_t *dev_priv ); 163
164extern void mga_do_dma_flush(drm_mga_private_t * dev_priv);
165extern void mga_do_dma_wrap_start(drm_mga_private_t * dev_priv);
166extern void mga_do_dma_wrap_end(drm_mga_private_t * dev_priv);
128 167
129extern int mga_freelist_put( drm_device_t *dev, drm_buf_t *buf ); 168extern int mga_freelist_put( drm_device_t *dev, drm_buf_t *buf );
130 169
131 /* mga_warp.c */ 170 /* mga_warp.c */
132extern int mga_warp_install_microcode( drm_mga_private_t *dev_priv ); 171extern unsigned int mga_warp_microcode_size(const drm_mga_private_t * dev_priv);
133extern int mga_warp_init( drm_mga_private_t *dev_priv ); 172extern int mga_warp_install_microcode(drm_mga_private_t * dev_priv);
134 173extern int mga_warp_init(drm_mga_private_t * dev_priv);
135extern int mga_driver_vblank_wait(drm_device_t *dev, unsigned int *sequence); 174
136extern irqreturn_t mga_driver_irq_handler( DRM_IRQ_ARGS ); 175 /* mga_irq.c */
137extern void mga_driver_irq_preinstall( drm_device_t *dev ); 176extern int mga_driver_fence_wait(drm_device_t * dev, unsigned int *sequence);
138extern void mga_driver_irq_postinstall( drm_device_t *dev ); 177extern int mga_driver_vblank_wait(drm_device_t * dev, unsigned int *sequence);
139extern void mga_driver_irq_uninstall( drm_device_t *dev ); 178extern irqreturn_t mga_driver_irq_handler(DRM_IRQ_ARGS);
179extern void mga_driver_irq_preinstall(drm_device_t * dev);
180extern void mga_driver_irq_postinstall(drm_device_t * dev);
181extern void mga_driver_irq_uninstall(drm_device_t * dev);
140extern long mga_compat_ioctl(struct file *filp, unsigned int cmd, 182extern long mga_compat_ioctl(struct file *filp, unsigned int cmd,
141 unsigned long arg); 183 unsigned long arg);
142 184
@@ -527,6 +569,12 @@ do { \
527 */ 569 */
528#define MGA_EXEC 0x0100 570#define MGA_EXEC 0x0100
529 571
572/* AGP PLL encoding (for G200 only).
573 */
574#define MGA_AGP_PLL 0x1e4c
575# define MGA_AGP2XPLL_DISABLE (0 << 0)
576# define MGA_AGP2XPLL_ENABLE (1 << 0)
577
530/* Warp registers 578/* Warp registers
531 */ 579 */
532#define MGA_WR0 0x2d00 580#define MGA_WR0 0x2d00
diff --git a/drivers/char/drm/mga_ioc32.c b/drivers/char/drm/mga_ioc32.c
index bc745cfa2095..77d738e75a4d 100644
--- a/drivers/char/drm/mga_ioc32.c
+++ b/drivers/char/drm/mga_ioc32.c
@@ -129,9 +129,76 @@ static int compat_mga_getparam(struct file *file, unsigned int cmd,
129 DRM_IOCTL_MGA_GETPARAM, (unsigned long)getparam); 129 DRM_IOCTL_MGA_GETPARAM, (unsigned long)getparam);
130} 130}
131 131
132typedef struct drm_mga_drm_bootstrap32 {
133 u32 texture_handle;
134 u32 texture_size;
135 u32 primary_size;
136 u32 secondary_bin_count;
137 u32 secondary_bin_size;
138 u32 agp_mode;
139 u8 agp_size;
140} drm_mga_dma_bootstrap32_t;
141
142static int compat_mga_dma_bootstrap(struct file *file, unsigned int cmd,
143 unsigned long arg)
144{
145 drm_mga_dma_bootstrap32_t dma_bootstrap32;
146 drm_mga_dma_bootstrap_t __user *dma_bootstrap;
147 int err;
148
149 if (copy_from_user(&dma_bootstrap32, (void __user *)arg,
150 sizeof(dma_bootstrap32)))
151 return -EFAULT;
152
153 dma_bootstrap = compat_alloc_user_space(sizeof(*dma_bootstrap));
154 if (!access_ok(VERIFY_WRITE, dma_bootstrap, sizeof(*dma_bootstrap))
155 || __put_user(dma_bootstrap32.texture_handle,
156 &dma_bootstrap->texture_handle)
157 || __put_user(dma_bootstrap32.texture_size,
158 &dma_bootstrap->texture_size)
159 || __put_user(dma_bootstrap32.primary_size,
160 &dma_bootstrap->primary_size)
161 || __put_user(dma_bootstrap32.secondary_bin_count,
162 &dma_bootstrap->secondary_bin_count)
163 || __put_user(dma_bootstrap32.secondary_bin_size,
164 &dma_bootstrap->secondary_bin_size)
165 || __put_user(dma_bootstrap32.agp_mode, &dma_bootstrap->agp_mode)
166 || __put_user(dma_bootstrap32.agp_size, &dma_bootstrap->agp_size))
167 return -EFAULT;
168
169 err = drm_ioctl(file->f_dentry->d_inode, file,
170 DRM_IOCTL_MGA_DMA_BOOTSTRAP,
171 (unsigned long)dma_bootstrap);
172 if (err)
173 return err;
174
175 if (__get_user(dma_bootstrap32.texture_handle,
176 &dma_bootstrap->texture_handle)
177 || __get_user(dma_bootstrap32.texture_size,
178 &dma_bootstrap->texture_size)
179 || __get_user(dma_bootstrap32.primary_size,
180 &dma_bootstrap->primary_size)
181 || __get_user(dma_bootstrap32.secondary_bin_count,
182 &dma_bootstrap->secondary_bin_count)
183 || __get_user(dma_bootstrap32.secondary_bin_size,
184 &dma_bootstrap->secondary_bin_size)
185 || __get_user(dma_bootstrap32.agp_mode,
186 &dma_bootstrap->agp_mode)
187 || __get_user(dma_bootstrap32.agp_size,
188 &dma_bootstrap->agp_size))
189 return -EFAULT;
190
191 if (copy_to_user((void __user *)arg, &dma_bootstrap32,
192 sizeof(dma_bootstrap32)))
193 return -EFAULT;
194
195 return 0;
196}
197
132drm_ioctl_compat_t *mga_compat_ioctls[] = { 198drm_ioctl_compat_t *mga_compat_ioctls[] = {
133 [DRM_MGA_INIT] = compat_mga_init, 199 [DRM_MGA_INIT] = compat_mga_init,
134 [DRM_MGA_GETPARAM] = compat_mga_getparam, 200 [DRM_MGA_GETPARAM] = compat_mga_getparam,
201 [DRM_MGA_DMA_BOOTSTRAP] = compat_mga_dma_bootstrap,
135}; 202};
136 203
137/** 204/**
diff --git a/drivers/char/drm/mga_irq.c b/drivers/char/drm/mga_irq.c
index bc0b6b5d43a6..52eaa4e788f9 100644
--- a/drivers/char/drm/mga_irq.c
+++ b/drivers/char/drm/mga_irq.c
@@ -41,15 +41,40 @@ irqreturn_t mga_driver_irq_handler( DRM_IRQ_ARGS )
41 drm_mga_private_t *dev_priv = 41 drm_mga_private_t *dev_priv =
42 (drm_mga_private_t *)dev->dev_private; 42 (drm_mga_private_t *)dev->dev_private;
43 int status; 43 int status;
44 int handled = 0;
45
46 status = MGA_READ(MGA_STATUS);
44 47
45 status = MGA_READ( MGA_STATUS );
46
47 /* VBLANK interrupt */ 48 /* VBLANK interrupt */
48 if ( status & MGA_VLINEPEN ) { 49 if ( status & MGA_VLINEPEN ) {
49 MGA_WRITE( MGA_ICLEAR, MGA_VLINEICLR ); 50 MGA_WRITE( MGA_ICLEAR, MGA_VLINEICLR );
50 atomic_inc(&dev->vbl_received); 51 atomic_inc(&dev->vbl_received);
51 DRM_WAKEUP(&dev->vbl_queue); 52 DRM_WAKEUP(&dev->vbl_queue);
52 drm_vbl_send_signals( dev ); 53 drm_vbl_send_signals(dev);
54 handled = 1;
55 }
56
57 /* SOFTRAP interrupt */
58 if (status & MGA_SOFTRAPEN) {
59 const u32 prim_start = MGA_READ(MGA_PRIMADDRESS);
60 const u32 prim_end = MGA_READ(MGA_PRIMEND);
61
62
63 MGA_WRITE(MGA_ICLEAR, MGA_SOFTRAPICLR);
64
65 /* In addition to clearing the interrupt-pending bit, we
66 * have to write to MGA_PRIMEND to re-start the DMA operation.
67 */
68 if ( (prim_start & ~0x03) != (prim_end & ~0x03) ) {
69 MGA_WRITE(MGA_PRIMEND, prim_end);
70 }
71
72 atomic_inc(&dev_priv->last_fence_retired);
73 DRM_WAKEUP(&dev_priv->fence_queue);
74 handled = 1;
75 }
76
77 if ( handled ) {
53 return IRQ_HANDLED; 78 return IRQ_HANDLED;
54 } 79 }
55 return IRQ_NONE; 80 return IRQ_NONE;
@@ -73,9 +98,28 @@ int mga_driver_vblank_wait(drm_device_t *dev, unsigned int *sequence)
73 return ret; 98 return ret;
74} 99}
75 100
76void mga_driver_irq_preinstall( drm_device_t *dev ) { 101int mga_driver_fence_wait(drm_device_t * dev, unsigned int *sequence)
77 drm_mga_private_t *dev_priv = 102{
78 (drm_mga_private_t *)dev->dev_private; 103 drm_mga_private_t *dev_priv = (drm_mga_private_t *) dev->dev_private;
104 unsigned int cur_fence;
105 int ret = 0;
106
107 /* Assume that the user has missed the current sequence number
108 * by about a day rather than she wants to wait for years
109 * using fences.
110 */
111 DRM_WAIT_ON(ret, dev_priv->fence_queue, 3 * DRM_HZ,
112 (((cur_fence = atomic_read(&dev_priv->last_fence_retired))
113 - *sequence) <= (1 << 23)));
114
115 *sequence = cur_fence;
116
117 return ret;
118}
119
120void mga_driver_irq_preinstall(drm_device_t * dev)
121{
122 drm_mga_private_t *dev_priv = (drm_mga_private_t *) dev->dev_private;
79 123
80 /* Disable *all* interrupts */ 124 /* Disable *all* interrupts */
81 MGA_WRITE( MGA_IEN, 0 ); 125 MGA_WRITE( MGA_IEN, 0 );
@@ -83,12 +127,14 @@ void mga_driver_irq_preinstall( drm_device_t *dev ) {
83 MGA_WRITE( MGA_ICLEAR, ~0 ); 127 MGA_WRITE( MGA_ICLEAR, ~0 );
84} 128}
85 129
86void mga_driver_irq_postinstall( drm_device_t *dev ) { 130void mga_driver_irq_postinstall(drm_device_t * dev)
87 drm_mga_private_t *dev_priv = 131{
88 (drm_mga_private_t *)dev->dev_private; 132 drm_mga_private_t *dev_priv = (drm_mga_private_t *) dev->dev_private;
133
134 DRM_INIT_WAITQUEUE( &dev_priv->fence_queue );
89 135
90 /* Turn on VBL interrupt */ 136 /* Turn on vertical blank interrupt and soft trap interrupt. */
91 MGA_WRITE( MGA_IEN, MGA_VLINEIEN ); 137 MGA_WRITE(MGA_IEN, MGA_VLINEIEN | MGA_SOFTRAPEN);
92} 138}
93 139
94void mga_driver_irq_uninstall( drm_device_t *dev ) { 140void mga_driver_irq_uninstall( drm_device_t *dev ) {
@@ -98,5 +144,7 @@ void mga_driver_irq_uninstall( drm_device_t *dev ) {
98 return; 144 return;
99 145
100 /* Disable *all* interrupts */ 146 /* Disable *all* interrupts */
101 MGA_WRITE( MGA_IEN, 0 ); 147 MGA_WRITE(MGA_IEN, 0);
148
149 dev->irq_enabled = 0;
102} 150}
diff --git a/drivers/char/drm/mga_state.c b/drivers/char/drm/mga_state.c
index 3c7a8f5ba501..05bbb4719376 100644
--- a/drivers/char/drm/mga_state.c
+++ b/drivers/char/drm/mga_state.c
@@ -53,16 +53,16 @@ static void mga_emit_clip_rect( drm_mga_private_t *dev_priv,
53 53
54 /* Force reset of DWGCTL on G400 (eliminates clip disable bit). 54 /* Force reset of DWGCTL on G400 (eliminates clip disable bit).
55 */ 55 */
56 if ( dev_priv->chipset == MGA_CARD_TYPE_G400 ) { 56 if (dev_priv->chipset == MGA_CARD_TYPE_G400) {
57 DMA_BLOCK( MGA_DWGCTL, ctx->dwgctl, 57 DMA_BLOCK(MGA_DWGCTL, ctx->dwgctl,
58 MGA_LEN + MGA_EXEC, 0x80000000, 58 MGA_LEN + MGA_EXEC, 0x80000000,
59 MGA_DWGCTL, ctx->dwgctl, 59 MGA_DWGCTL, ctx->dwgctl,
60 MGA_LEN + MGA_EXEC, 0x80000000 ); 60 MGA_LEN + MGA_EXEC, 0x80000000);
61 } 61 }
62 DMA_BLOCK( MGA_DMAPAD, 0x00000000, 62 DMA_BLOCK(MGA_DMAPAD, 0x00000000,
63 MGA_CXBNDRY, (box->x2 << 16) | box->x1, 63 MGA_CXBNDRY, ((box->x2 - 1) << 16) | box->x1,
64 MGA_YTOP, box->y1 * pitch, 64 MGA_YTOP, box->y1 * pitch,
65 MGA_YBOT, box->y2 * pitch ); 65 MGA_YBOT, (box->y2 - 1) * pitch);
66 66
67 ADVANCE_DMA(); 67 ADVANCE_DMA();
68} 68}
@@ -260,12 +260,11 @@ static __inline__ void mga_g200_emit_pipe( drm_mga_private_t *dev_priv )
260 260
261 /* Padding required to to hardware bug. 261 /* Padding required to to hardware bug.
262 */ 262 */
263 DMA_BLOCK( MGA_DMAPAD, 0xffffffff, 263 DMA_BLOCK(MGA_DMAPAD, 0xffffffff,
264 MGA_DMAPAD, 0xffffffff, 264 MGA_DMAPAD, 0xffffffff,
265 MGA_DMAPAD, 0xffffffff, 265 MGA_DMAPAD, 0xffffffff,
266 MGA_WIADDR, (dev_priv->warp_pipe_phys[pipe] | 266 MGA_WIADDR, (dev_priv->warp_pipe_phys[pipe] |
267 MGA_WMODE_START | 267 MGA_WMODE_START | dev_priv->wagp_enable));
268 MGA_WAGP_ENABLE) );
269 268
270 ADVANCE_DMA(); 269 ADVANCE_DMA();
271} 270}
@@ -342,12 +341,11 @@ static __inline__ void mga_g400_emit_pipe( drm_mga_private_t *dev_priv )
342 MGA_WR60, MGA_G400_WR_MAGIC ); /* tex1 height */ 341 MGA_WR60, MGA_G400_WR_MAGIC ); /* tex1 height */
343 342
344 /* Padding required to to hardware bug */ 343 /* Padding required to to hardware bug */
345 DMA_BLOCK( MGA_DMAPAD, 0xffffffff, 344 DMA_BLOCK(MGA_DMAPAD, 0xffffffff,
346 MGA_DMAPAD, 0xffffffff, 345 MGA_DMAPAD, 0xffffffff,
347 MGA_DMAPAD, 0xffffffff, 346 MGA_DMAPAD, 0xffffffff,
348 MGA_WIADDR2, (dev_priv->warp_pipe_phys[pipe] | 347 MGA_WIADDR2, (dev_priv->warp_pipe_phys[pipe] |
349 MGA_WMODE_START | 348 MGA_WMODE_START | dev_priv->wagp_enable));
350 MGA_WAGP_ENABLE) );
351 349
352 ADVANCE_DMA(); 350 ADVANCE_DMA();
353} 351}
@@ -459,9 +457,9 @@ static int mga_verify_state( drm_mga_private_t *dev_priv )
459 if ( dirty & MGA_UPLOAD_TEX0 ) 457 if ( dirty & MGA_UPLOAD_TEX0 )
460 ret |= mga_verify_tex( dev_priv, 0 ); 458 ret |= mga_verify_tex( dev_priv, 0 );
461 459
462 if ( dev_priv->chipset == MGA_CARD_TYPE_G400 ) { 460 if (dev_priv->chipset >= MGA_CARD_TYPE_G400) {
463 if ( dirty & MGA_UPLOAD_TEX1 ) 461 if (dirty & MGA_UPLOAD_TEX1)
464 ret |= mga_verify_tex( dev_priv, 1 ); 462 ret |= mga_verify_tex(dev_priv, 1);
465 463
466 if ( dirty & MGA_UPLOAD_PIPE ) 464 if ( dirty & MGA_UPLOAD_PIPE )
467 ret |= ( sarea_priv->warp_pipe > MGA_MAX_G400_PIPES ); 465 ret |= ( sarea_priv->warp_pipe > MGA_MAX_G400_PIPES );
@@ -686,12 +684,12 @@ static void mga_dma_dispatch_vertex( drm_device_t *dev, drm_buf_t *buf )
686 684
687 BEGIN_DMA( 1 ); 685 BEGIN_DMA( 1 );
688 686
689 DMA_BLOCK( MGA_DMAPAD, 0x00000000, 687 DMA_BLOCK(MGA_DMAPAD, 0x00000000,
690 MGA_DMAPAD, 0x00000000, 688 MGA_DMAPAD, 0x00000000,
691 MGA_SECADDRESS, (address | 689 MGA_SECADDRESS, (address |
692 MGA_DMA_VERTEX), 690 MGA_DMA_VERTEX),
693 MGA_SECEND, ((address + length) | 691 MGA_SECEND, ((address + length) |
694 MGA_PAGPXFER) ); 692 dev_priv->dma_access));
695 693
696 ADVANCE_DMA(); 694 ADVANCE_DMA();
697 } while ( ++i < sarea_priv->nbox ); 695 } while ( ++i < sarea_priv->nbox );
@@ -733,11 +731,11 @@ static void mga_dma_dispatch_indices( drm_device_t *dev, drm_buf_t *buf,
733 731
734 BEGIN_DMA( 1 ); 732 BEGIN_DMA( 1 );
735 733
736 DMA_BLOCK( MGA_DMAPAD, 0x00000000, 734 DMA_BLOCK(MGA_DMAPAD, 0x00000000,
737 MGA_DMAPAD, 0x00000000, 735 MGA_DMAPAD, 0x00000000,
738 MGA_SETUPADDRESS, address + start, 736 MGA_SETUPADDRESS, address + start,
739 MGA_SETUPEND, ((address + end) | 737 MGA_SETUPEND, ((address + end) |
740 MGA_PAGPXFER) ); 738 dev_priv->dma_access));
741 739
742 ADVANCE_DMA(); 740 ADVANCE_DMA();
743 } while ( ++i < sarea_priv->nbox ); 741 } while ( ++i < sarea_priv->nbox );
@@ -764,7 +762,7 @@ static void mga_dma_dispatch_iload( drm_device_t *dev, drm_buf_t *buf,
764 drm_mga_private_t *dev_priv = dev->dev_private; 762 drm_mga_private_t *dev_priv = dev->dev_private;
765 drm_mga_buf_priv_t *buf_priv = buf->dev_private; 763 drm_mga_buf_priv_t *buf_priv = buf->dev_private;
766 drm_mga_context_regs_t *ctx = &dev_priv->sarea_priv->context_state; 764 drm_mga_context_regs_t *ctx = &dev_priv->sarea_priv->context_state;
767 u32 srcorg = buf->bus_address | MGA_SRCACC_AGP | MGA_SRCMAP_SYSMEM; 765 u32 srcorg = buf->bus_address | dev_priv->dma_access | MGA_SRCMAP_SYSMEM;
768 u32 y2; 766 u32 y2;
769 DMA_LOCALS; 767 DMA_LOCALS;
770 DRM_DEBUG( "buf=%d used=%d\n", buf->idx, buf->used ); 768 DRM_DEBUG( "buf=%d used=%d\n", buf->idx, buf->used );
@@ -1095,6 +1093,9 @@ static int mga_getparam( DRM_IOCTL_ARGS )
1095 case MGA_PARAM_IRQ_NR: 1093 case MGA_PARAM_IRQ_NR:
1096 value = dev->irq; 1094 value = dev->irq;
1097 break; 1095 break;
1096 case MGA_PARAM_CARD_TYPE:
1097 value = dev_priv->chipset;
1098 break;
1098 default: 1099 default:
1099 return DRM_ERR(EINVAL); 1100 return DRM_ERR(EINVAL);
1100 } 1101 }
@@ -1107,17 +1108,82 @@ static int mga_getparam( DRM_IOCTL_ARGS )
1107 return 0; 1108 return 0;
1108} 1109}
1109 1110
1111static int mga_set_fence(DRM_IOCTL_ARGS)
1112{
1113 DRM_DEVICE;
1114 drm_mga_private_t *dev_priv = dev->dev_private;
1115 u32 temp;
1116 DMA_LOCALS;
1117
1118 if (!dev_priv) {
1119 DRM_ERROR("%s called with no initialization\n", __FUNCTION__);
1120 return DRM_ERR(EINVAL);
1121 }
1122
1123 DRM_DEBUG("pid=%d\n", DRM_CURRENTPID);
1124
1125 /* I would normal do this assignment in the declaration of temp,
1126 * but dev_priv may be NULL.
1127 */
1128
1129 temp = dev_priv->next_fence_to_post;
1130 dev_priv->next_fence_to_post++;
1131
1132 BEGIN_DMA(1);
1133 DMA_BLOCK(MGA_DMAPAD, 0x00000000,
1134 MGA_DMAPAD, 0x00000000,
1135 MGA_DMAPAD, 0x00000000,
1136 MGA_SOFTRAP, 0x00000000);
1137 ADVANCE_DMA();
1138
1139 if (DRM_COPY_TO_USER( (u32 __user *) data, & temp, sizeof(u32))) {
1140 DRM_ERROR("copy_to_user\n");
1141 return DRM_ERR(EFAULT);
1142 }
1143
1144 return 0;
1145}
1146
1147static int mga_wait_fence(DRM_IOCTL_ARGS)
1148{
1149 DRM_DEVICE;
1150 drm_mga_private_t *dev_priv = dev->dev_private;
1151 u32 fence;
1152
1153 if (!dev_priv) {
1154 DRM_ERROR("%s called with no initialization\n", __FUNCTION__);
1155 return DRM_ERR(EINVAL);
1156 }
1157
1158 DRM_COPY_FROM_USER_IOCTL(fence, (u32 __user *) data, sizeof(u32));
1159
1160 DRM_DEBUG("pid=%d\n", DRM_CURRENTPID);
1161
1162 mga_driver_fence_wait(dev, & fence);
1163
1164 if (DRM_COPY_TO_USER( (u32 __user *) data, & fence, sizeof(u32))) {
1165 DRM_ERROR("copy_to_user\n");
1166 return DRM_ERR(EFAULT);
1167 }
1168
1169 return 0;
1170}
1171
1110drm_ioctl_desc_t mga_ioctls[] = { 1172drm_ioctl_desc_t mga_ioctls[] = {
1111 [DRM_IOCTL_NR(DRM_MGA_INIT)] = { mga_dma_init, 1, 1 }, 1173 [DRM_IOCTL_NR(DRM_MGA_INIT)] = {mga_dma_init, 1, 1},
1112 [DRM_IOCTL_NR(DRM_MGA_FLUSH)] = { mga_dma_flush, 1, 0 }, 1174 [DRM_IOCTL_NR(DRM_MGA_FLUSH)] = {mga_dma_flush, 1, 0},
1113 [DRM_IOCTL_NR(DRM_MGA_RESET)] = { mga_dma_reset, 1, 0 }, 1175 [DRM_IOCTL_NR(DRM_MGA_RESET)] = {mga_dma_reset, 1, 0},
1114 [DRM_IOCTL_NR(DRM_MGA_SWAP)] = { mga_dma_swap, 1, 0 }, 1176 [DRM_IOCTL_NR(DRM_MGA_SWAP)] = {mga_dma_swap, 1, 0},
1115 [DRM_IOCTL_NR(DRM_MGA_CLEAR)] = { mga_dma_clear, 1, 0 }, 1177 [DRM_IOCTL_NR(DRM_MGA_CLEAR)] = {mga_dma_clear, 1, 0},
1116 [DRM_IOCTL_NR(DRM_MGA_VERTEX)] = { mga_dma_vertex, 1, 0 }, 1178 [DRM_IOCTL_NR(DRM_MGA_VERTEX)] = {mga_dma_vertex, 1, 0},
1117 [DRM_IOCTL_NR(DRM_MGA_INDICES)] = { mga_dma_indices, 1, 0 }, 1179 [DRM_IOCTL_NR(DRM_MGA_INDICES)] = {mga_dma_indices, 1, 0},
1118 [DRM_IOCTL_NR(DRM_MGA_ILOAD)] = { mga_dma_iload, 1, 0 }, 1180 [DRM_IOCTL_NR(DRM_MGA_ILOAD)] = {mga_dma_iload, 1, 0},
1119 [DRM_IOCTL_NR(DRM_MGA_BLIT)] = { mga_dma_blit, 1, 0 }, 1181 [DRM_IOCTL_NR(DRM_MGA_BLIT)] = {mga_dma_blit, 1, 0},
1120 [DRM_IOCTL_NR(DRM_MGA_GETPARAM)]= { mga_getparam, 1, 0 }, 1182 [DRM_IOCTL_NR(DRM_MGA_GETPARAM)] = {mga_getparam, 1, 0},
1183 [DRM_IOCTL_NR(DRM_MGA_SET_FENCE)] = {mga_set_fence, 1, 0},
1184 [DRM_IOCTL_NR(DRM_MGA_WAIT_FENCE)] = {mga_wait_fence, 1, 0},
1185 [DRM_IOCTL_NR(DRM_MGA_DMA_BOOTSTRAP)] = {mga_dma_bootstrap, 1, 1},
1186
1121}; 1187};
1122 1188
1123int mga_max_ioctl = DRM_ARRAY_SIZE(mga_ioctls); 1189int mga_max_ioctl = DRM_ARRAY_SIZE(mga_ioctls);
diff --git a/drivers/char/drm/mga_warp.c b/drivers/char/drm/mga_warp.c
index 0a3a0cc700dc..55ccc8a0ac29 100644
--- a/drivers/char/drm/mga_warp.c
+++ b/drivers/char/drm/mga_warp.c
@@ -48,65 +48,52 @@ do { \
48 vcbase += WARP_UCODE_SIZE( which ); \ 48 vcbase += WARP_UCODE_SIZE( which ); \
49} while (0) 49} while (0)
50 50
51 51static const unsigned int mga_warp_g400_microcode_size =
52static unsigned int mga_warp_g400_microcode_size( drm_mga_private_t *dev_priv ) 52 (WARP_UCODE_SIZE(warp_g400_tgz) +
53{ 53 WARP_UCODE_SIZE(warp_g400_tgza) +
54 unsigned int size; 54 WARP_UCODE_SIZE(warp_g400_tgzaf) +
55 55 WARP_UCODE_SIZE(warp_g400_tgzf) +
56 size = ( WARP_UCODE_SIZE( warp_g400_tgz ) + 56 WARP_UCODE_SIZE(warp_g400_tgzs) +
57 WARP_UCODE_SIZE( warp_g400_tgza ) + 57 WARP_UCODE_SIZE(warp_g400_tgzsa) +
58 WARP_UCODE_SIZE( warp_g400_tgzaf ) + 58 WARP_UCODE_SIZE(warp_g400_tgzsaf) +
59 WARP_UCODE_SIZE( warp_g400_tgzf ) + 59 WARP_UCODE_SIZE(warp_g400_tgzsf) +
60 WARP_UCODE_SIZE( warp_g400_tgzs ) + 60 WARP_UCODE_SIZE(warp_g400_t2gz) +
61 WARP_UCODE_SIZE( warp_g400_tgzsa ) + 61 WARP_UCODE_SIZE(warp_g400_t2gza) +
62 WARP_UCODE_SIZE( warp_g400_tgzsaf ) + 62 WARP_UCODE_SIZE(warp_g400_t2gzaf) +
63 WARP_UCODE_SIZE( warp_g400_tgzsf ) + 63 WARP_UCODE_SIZE(warp_g400_t2gzf) +
64 WARP_UCODE_SIZE( warp_g400_t2gz ) + 64 WARP_UCODE_SIZE(warp_g400_t2gzs) +
65 WARP_UCODE_SIZE( warp_g400_t2gza ) + 65 WARP_UCODE_SIZE(warp_g400_t2gzsa) +
66 WARP_UCODE_SIZE( warp_g400_t2gzaf ) + 66 WARP_UCODE_SIZE(warp_g400_t2gzsaf) +
67 WARP_UCODE_SIZE( warp_g400_t2gzf ) + 67 WARP_UCODE_SIZE(warp_g400_t2gzsf));
68 WARP_UCODE_SIZE( warp_g400_t2gzs ) + 68
69 WARP_UCODE_SIZE( warp_g400_t2gzsa ) + 69static const unsigned int mga_warp_g200_microcode_size =
70 WARP_UCODE_SIZE( warp_g400_t2gzsaf ) + 70 (WARP_UCODE_SIZE(warp_g200_tgz) +
71 WARP_UCODE_SIZE( warp_g400_t2gzsf ) ); 71 WARP_UCODE_SIZE(warp_g200_tgza) +
72 72 WARP_UCODE_SIZE(warp_g200_tgzaf) +
73 size = PAGE_ALIGN( size ); 73 WARP_UCODE_SIZE(warp_g200_tgzf) +
74 74 WARP_UCODE_SIZE(warp_g200_tgzs) +
75 DRM_DEBUG( "G400 ucode size = %d bytes\n", size ); 75 WARP_UCODE_SIZE(warp_g200_tgzsa) +
76 return size; 76 WARP_UCODE_SIZE(warp_g200_tgzsaf) +
77} 77 WARP_UCODE_SIZE(warp_g200_tgzsf));
78 78
79static unsigned int mga_warp_g200_microcode_size( drm_mga_private_t *dev_priv ) 79
80unsigned int mga_warp_microcode_size(const drm_mga_private_t * dev_priv)
80{ 81{
81 unsigned int size; 82 switch (dev_priv->chipset) {
82 83 case MGA_CARD_TYPE_G400:
83 size = ( WARP_UCODE_SIZE( warp_g200_tgz ) + 84 case MGA_CARD_TYPE_G550:
84 WARP_UCODE_SIZE( warp_g200_tgza ) + 85 return PAGE_ALIGN(mga_warp_g400_microcode_size);
85 WARP_UCODE_SIZE( warp_g200_tgzaf ) + 86 case MGA_CARD_TYPE_G200:
86 WARP_UCODE_SIZE( warp_g200_tgzf ) + 87 return PAGE_ALIGN(mga_warp_g200_microcode_size);
87 WARP_UCODE_SIZE( warp_g200_tgzs ) + 88 default:
88 WARP_UCODE_SIZE( warp_g200_tgzsa ) + 89 return 0;
89 WARP_UCODE_SIZE( warp_g200_tgzsaf ) + 90 }
90 WARP_UCODE_SIZE( warp_g200_tgzsf ) );
91
92 size = PAGE_ALIGN( size );
93
94 DRM_DEBUG( "G200 ucode size = %d bytes\n", size );
95 return size;
96} 91}
97 92
98static int mga_warp_install_g400_microcode( drm_mga_private_t *dev_priv ) 93static int mga_warp_install_g400_microcode( drm_mga_private_t *dev_priv )
99{ 94{
100 unsigned char *vcbase = dev_priv->warp->handle; 95 unsigned char *vcbase = dev_priv->warp->handle;
101 unsigned long pcbase = dev_priv->warp->offset; 96 unsigned long pcbase = dev_priv->warp->offset;
102 unsigned int size;
103
104 size = mga_warp_g400_microcode_size( dev_priv );
105 if ( size > dev_priv->warp->size ) {
106 DRM_ERROR( "microcode too large! (%u > %lu)\n",
107 size, dev_priv->warp->size );
108 return DRM_ERR(ENOMEM);
109 }
110 97
111 memset( dev_priv->warp_pipe_phys, 0, 98 memset( dev_priv->warp_pipe_phys, 0,
112 sizeof(dev_priv->warp_pipe_phys) ); 99 sizeof(dev_priv->warp_pipe_phys) );
@@ -136,35 +123,36 @@ static int mga_warp_install_g200_microcode( drm_mga_private_t *dev_priv )
136{ 123{
137 unsigned char *vcbase = dev_priv->warp->handle; 124 unsigned char *vcbase = dev_priv->warp->handle;
138 unsigned long pcbase = dev_priv->warp->offset; 125 unsigned long pcbase = dev_priv->warp->offset;
139 unsigned int size;
140
141 size = mga_warp_g200_microcode_size( dev_priv );
142 if ( size > dev_priv->warp->size ) {
143 DRM_ERROR( "microcode too large! (%u > %lu)\n",
144 size, dev_priv->warp->size );
145 return DRM_ERR(ENOMEM);
146 }
147 126
148 memset( dev_priv->warp_pipe_phys, 0, 127 memset(dev_priv->warp_pipe_phys, 0, sizeof(dev_priv->warp_pipe_phys));
149 sizeof(dev_priv->warp_pipe_phys) );
150 128
151 WARP_UCODE_INSTALL( warp_g200_tgz, MGA_WARP_TGZ ); 129 WARP_UCODE_INSTALL(warp_g200_tgz, MGA_WARP_TGZ);
152 WARP_UCODE_INSTALL( warp_g200_tgzf, MGA_WARP_TGZF ); 130 WARP_UCODE_INSTALL(warp_g200_tgzf, MGA_WARP_TGZF);
153 WARP_UCODE_INSTALL( warp_g200_tgza, MGA_WARP_TGZA ); 131 WARP_UCODE_INSTALL(warp_g200_tgza, MGA_WARP_TGZA);
154 WARP_UCODE_INSTALL( warp_g200_tgzaf, MGA_WARP_TGZAF ); 132 WARP_UCODE_INSTALL(warp_g200_tgzaf, MGA_WARP_TGZAF);
155 WARP_UCODE_INSTALL( warp_g200_tgzs, MGA_WARP_TGZS ); 133 WARP_UCODE_INSTALL(warp_g200_tgzs, MGA_WARP_TGZS);
156 WARP_UCODE_INSTALL( warp_g200_tgzsf, MGA_WARP_TGZSF ); 134 WARP_UCODE_INSTALL(warp_g200_tgzsf, MGA_WARP_TGZSF);
157 WARP_UCODE_INSTALL( warp_g200_tgzsa, MGA_WARP_TGZSA ); 135 WARP_UCODE_INSTALL(warp_g200_tgzsa, MGA_WARP_TGZSA);
158 WARP_UCODE_INSTALL( warp_g200_tgzsaf, MGA_WARP_TGZSAF ); 136 WARP_UCODE_INSTALL(warp_g200_tgzsaf, MGA_WARP_TGZSAF);
159 137
160 return 0; 138 return 0;
161} 139}
162 140
163int mga_warp_install_microcode( drm_mga_private_t *dev_priv ) 141int mga_warp_install_microcode( drm_mga_private_t *dev_priv )
164{ 142{
165 switch ( dev_priv->chipset ) { 143 const unsigned int size = mga_warp_microcode_size(dev_priv);
144
145 DRM_DEBUG("MGA ucode size = %d bytes\n", size);
146 if (size > dev_priv->warp->size) {
147 DRM_ERROR("microcode too large! (%u > %lu)\n",
148 size, dev_priv->warp->size);
149 return DRM_ERR(ENOMEM);
150 }
151
152 switch (dev_priv->chipset) {
166 case MGA_CARD_TYPE_G400: 153 case MGA_CARD_TYPE_G400:
167 return mga_warp_install_g400_microcode( dev_priv ); 154 case MGA_CARD_TYPE_G550:
155 return mga_warp_install_g400_microcode(dev_priv);
168 case MGA_CARD_TYPE_G200: 156 case MGA_CARD_TYPE_G200:
169 return mga_warp_install_g200_microcode( dev_priv ); 157 return mga_warp_install_g200_microcode( dev_priv );
170 default: 158 default:
@@ -182,10 +170,11 @@ int mga_warp_init( drm_mga_private_t *dev_priv )
182 */ 170 */
183 switch ( dev_priv->chipset ) { 171 switch ( dev_priv->chipset ) {
184 case MGA_CARD_TYPE_G400: 172 case MGA_CARD_TYPE_G400:
185 MGA_WRITE( MGA_WIADDR2, MGA_WMODE_SUSPEND ); 173 case MGA_CARD_TYPE_G550:
186 MGA_WRITE( MGA_WGETMSB, 0x00000E00 ); 174 MGA_WRITE(MGA_WIADDR2, MGA_WMODE_SUSPEND);
187 MGA_WRITE( MGA_WVRTXSZ, 0x00001807 ); 175 MGA_WRITE(MGA_WGETMSB, 0x00000E00);
188 MGA_WRITE( MGA_WACCEPTSEQ, 0x18000000 ); 176 MGA_WRITE(MGA_WVRTXSZ, 0x00001807);
177 MGA_WRITE(MGA_WACCEPTSEQ, 0x18000000);
189 break; 178 break;
190 case MGA_CARD_TYPE_G200: 179 case MGA_CARD_TYPE_G200:
191 MGA_WRITE( MGA_WIADDR, MGA_WMODE_SUSPEND ); 180 MGA_WRITE( MGA_WIADDR, MGA_WMODE_SUSPEND );
diff --git a/drivers/char/drm/r128_cce.c b/drivers/char/drm/r128_cce.c
index 08ed8d01d9d9..895152206b31 100644
--- a/drivers/char/drm/r128_cce.c
+++ b/drivers/char/drm/r128_cce.c
@@ -326,7 +326,8 @@ static void r128_cce_init_ring_buffer( drm_device_t *dev,
326 ring_start = dev_priv->cce_ring->offset - dev->agp->base; 326 ring_start = dev_priv->cce_ring->offset - dev->agp->base;
327 else 327 else
328#endif 328#endif
329 ring_start = dev_priv->cce_ring->offset - dev->sg->handle; 329 ring_start = dev_priv->cce_ring->offset -
330 (unsigned long)dev->sg->virtual;
330 331
331 R128_WRITE( R128_PM4_BUFFER_OFFSET, ring_start | R128_AGP_OFFSET ); 332 R128_WRITE( R128_PM4_BUFFER_OFFSET, ring_start | R128_AGP_OFFSET );
332 333
@@ -487,6 +488,7 @@ static int r128_do_init_cce( drm_device_t *dev, drm_r128_init_t *init )
487 r128_do_cleanup_cce( dev ); 488 r128_do_cleanup_cce( dev );
488 return DRM_ERR(EINVAL); 489 return DRM_ERR(EINVAL);
489 } 490 }
491 dev->agp_buffer_token = init->buffers_offset;
490 dev->agp_buffer_map = drm_core_findmap(dev, init->buffers_offset); 492 dev->agp_buffer_map = drm_core_findmap(dev, init->buffers_offset);
491 if(!dev->agp_buffer_map) { 493 if(!dev->agp_buffer_map) {
492 DRM_ERROR("could not find dma buffer region!\n"); 494 DRM_ERROR("could not find dma buffer region!\n");
@@ -537,7 +539,7 @@ static int r128_do_init_cce( drm_device_t *dev, drm_r128_init_t *init )
537 dev_priv->cce_buffers_offset = dev->agp->base; 539 dev_priv->cce_buffers_offset = dev->agp->base;
538 else 540 else
539#endif 541#endif
540 dev_priv->cce_buffers_offset = dev->sg->handle; 542 dev_priv->cce_buffers_offset = (unsigned long)dev->sg->virtual;
541 543
542 dev_priv->ring.start = (u32 *)dev_priv->cce_ring->handle; 544 dev_priv->ring.start = (u32 *)dev_priv->cce_ring->handle;
543 dev_priv->ring.end = ((u32 *)dev_priv->cce_ring->handle 545 dev_priv->ring.end = ((u32 *)dev_priv->cce_ring->handle
diff --git a/drivers/char/drm/r128_drm.h b/drivers/char/drm/r128_drm.h
index 0cba17d1e0ff..b616cd3ed2cd 100644
--- a/drivers/char/drm/r128_drm.h
+++ b/drivers/char/drm/r128_drm.h
@@ -215,7 +215,7 @@ typedef struct drm_r128_sarea {
215#define DRM_IOCTL_R128_INDIRECT DRM_IOWR(DRM_COMMAND_BASE + DRM_R128_INDIRECT, drm_r128_indirect_t) 215#define DRM_IOCTL_R128_INDIRECT DRM_IOWR(DRM_COMMAND_BASE + DRM_R128_INDIRECT, drm_r128_indirect_t)
216#define DRM_IOCTL_R128_FULLSCREEN DRM_IOW( DRM_COMMAND_BASE + DRM_R128_FULLSCREEN, drm_r128_fullscreen_t) 216#define DRM_IOCTL_R128_FULLSCREEN DRM_IOW( DRM_COMMAND_BASE + DRM_R128_FULLSCREEN, drm_r128_fullscreen_t)
217#define DRM_IOCTL_R128_CLEAR2 DRM_IOW( DRM_COMMAND_BASE + DRM_R128_CLEAR2, drm_r128_clear2_t) 217#define DRM_IOCTL_R128_CLEAR2 DRM_IOW( DRM_COMMAND_BASE + DRM_R128_CLEAR2, drm_r128_clear2_t)
218#define DRM_IOCTL_R128_GETPARAM DRM_IOW( DRM_COMMAND_BASE + DRM_R128_GETPARAM, drm_r128_getparam_t) 218#define DRM_IOCTL_R128_GETPARAM DRM_IOWR( DRM_COMMAND_BASE + DRM_R128_GETPARAM, drm_r128_getparam_t)
219#define DRM_IOCTL_R128_FLIP DRM_IO( DRM_COMMAND_BASE + DRM_R128_FLIP) 219#define DRM_IOCTL_R128_FLIP DRM_IO( DRM_COMMAND_BASE + DRM_R128_FLIP)
220 220
221typedef struct drm_r128_init { 221typedef struct drm_r128_init {
diff --git a/drivers/char/drm/r300_cmdbuf.c b/drivers/char/drm/r300_cmdbuf.c
new file mode 100644
index 000000000000..623f1f460cb5
--- /dev/null
+++ b/drivers/char/drm/r300_cmdbuf.c
@@ -0,0 +1,801 @@
1/* r300_cmdbuf.c -- Command buffer emission for R300 -*- linux-c -*-
2 *
3 * Copyright (C) The Weather Channel, Inc. 2002.
4 * Copyright (C) 2004 Nicolai Haehnle.
5 * All Rights Reserved.
6 *
7 * The Weather Channel (TM) funded Tungsten Graphics to develop the
8 * initial release of the Radeon 8500 driver under the XFree86 license.
9 * This notice must be preserved.
10 *
11 * Permission is hereby granted, free of charge, to any person obtaining a
12 * copy of this software and associated documentation files (the "Software"),
13 * to deal in the Software without restriction, including without limitation
14 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
15 * and/or sell copies of the Software, and to permit persons to whom the
16 * Software is furnished to do so, subject to the following conditions:
17 *
18 * The above copyright notice and this permission notice (including the next
19 * paragraph) shall be included in all copies or substantial portions of the
20 * Software.
21 *
22 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
23 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
24 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
25 * PRECISION INSIGHT AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
26 * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
27 * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
28 * DEALINGS IN THE SOFTWARE.
29 *
30 * Authors:
31 * Nicolai Haehnle <prefect_@gmx.net>
32 */
33
34#include "drmP.h"
35#include "drm.h"
36#include "radeon_drm.h"
37#include "radeon_drv.h"
38#include "r300_reg.h"
39
40
41#define R300_SIMULTANEOUS_CLIPRECTS 4
42
43/* Values for R300_RE_CLIPRECT_CNTL depending on the number of cliprects
44 */
45static const int r300_cliprect_cntl[4] = {
46 0xAAAA,
47 0xEEEE,
48 0xFEFE,
49 0xFFFE
50};
51
52
53/**
54 * Emit up to R300_SIMULTANEOUS_CLIPRECTS cliprects from the given command
55 * buffer, starting with index n.
56 */
57static int r300_emit_cliprects(drm_radeon_private_t* dev_priv,
58 drm_radeon_cmd_buffer_t* cmdbuf,
59 int n)
60{
61 drm_clip_rect_t box;
62 int nr;
63 int i;
64 RING_LOCALS;
65
66 nr = cmdbuf->nbox - n;
67 if (nr > R300_SIMULTANEOUS_CLIPRECTS)
68 nr = R300_SIMULTANEOUS_CLIPRECTS;
69
70 DRM_DEBUG("%i cliprects\n", nr);
71
72 if (nr) {
73 BEGIN_RING(6 + nr*2);
74 OUT_RING( CP_PACKET0( R300_RE_CLIPRECT_TL_0, nr*2 - 1 ) );
75
76 for(i = 0; i < nr; ++i) {
77 if (DRM_COPY_FROM_USER_UNCHECKED(&box, &cmdbuf->boxes[n+i], sizeof(box))) {
78 DRM_ERROR("copy cliprect faulted\n");
79 return DRM_ERR(EFAULT);
80 }
81
82 box.x1 = (box.x1 + R300_CLIPRECT_OFFSET) & R300_CLIPRECT_MASK;
83 box.y1 = (box.y1 + R300_CLIPRECT_OFFSET) & R300_CLIPRECT_MASK;
84 box.x2 = (box.x2 + R300_CLIPRECT_OFFSET) & R300_CLIPRECT_MASK;
85 box.y2 = (box.y2 + R300_CLIPRECT_OFFSET) & R300_CLIPRECT_MASK;
86
87 OUT_RING((box.x1 << R300_CLIPRECT_X_SHIFT) |
88 (box.y1 << R300_CLIPRECT_Y_SHIFT));
89 OUT_RING((box.x2 << R300_CLIPRECT_X_SHIFT) |
90 (box.y2 << R300_CLIPRECT_Y_SHIFT));
91 }
92
93 OUT_RING_REG( R300_RE_CLIPRECT_CNTL, r300_cliprect_cntl[nr-1] );
94
95 /* TODO/SECURITY: Force scissors to a safe value, otherwise the
96 * client might be able to trample over memory.
97 * The impact should be very limited, but I'd rather be safe than
98 * sorry.
99 */
100 OUT_RING( CP_PACKET0( R300_RE_SCISSORS_TL, 1 ) );
101 OUT_RING( 0 );
102 OUT_RING( R300_SCISSORS_X_MASK | R300_SCISSORS_Y_MASK );
103 ADVANCE_RING();
104 } else {
105 /* Why we allow zero cliprect rendering:
106 * There are some commands in a command buffer that must be submitted
107 * even when there are no cliprects, e.g. DMA buffer discard
108 * or state setting (though state setting could be avoided by
109 * simulating a loss of context).
110 *
111 * Now since the cmdbuf interface is so chaotic right now (and is
112 * bound to remain that way for a bit until things settle down),
113 * it is basically impossible to filter out the commands that are
114 * necessary and those that aren't.
115 *
116 * So I choose the safe way and don't do any filtering at all;
117 * instead, I simply set up the engine so that all rendering
118 * can't produce any fragments.
119 */
120 BEGIN_RING(2);
121 OUT_RING_REG( R300_RE_CLIPRECT_CNTL, 0 );
122 ADVANCE_RING();
123 }
124
125 return 0;
126}
127
128u8 r300_reg_flags[0x10000>>2];
129
130
131void r300_init_reg_flags(void)
132{
133 int i;
134 memset(r300_reg_flags, 0, 0x10000>>2);
135 #define ADD_RANGE_MARK(reg, count,mark) \
136 for(i=((reg)>>2);i<((reg)>>2)+(count);i++)\
137 r300_reg_flags[i]|=(mark);
138
139 #define MARK_SAFE 1
140 #define MARK_CHECK_OFFSET 2
141
142 #define ADD_RANGE(reg, count) ADD_RANGE_MARK(reg, count, MARK_SAFE)
143
144 /* these match cmducs() command in r300_driver/r300/r300_cmdbuf.c */
145 ADD_RANGE(R300_SE_VPORT_XSCALE, 6);
146 ADD_RANGE(0x2080, 1);
147 ADD_RANGE(R300_SE_VTE_CNTL, 2);
148 ADD_RANGE(0x2134, 2);
149 ADD_RANGE(0x2140, 1);
150 ADD_RANGE(R300_VAP_INPUT_CNTL_0, 2);
151 ADD_RANGE(0x21DC, 1);
152 ADD_RANGE(0x221C, 1);
153 ADD_RANGE(0x2220, 4);
154 ADD_RANGE(0x2288, 1);
155 ADD_RANGE(R300_VAP_OUTPUT_VTX_FMT_0, 2);
156 ADD_RANGE(R300_VAP_PVS_CNTL_1, 3);
157 ADD_RANGE(R300_GB_ENABLE, 1);
158 ADD_RANGE(R300_GB_MSPOS0, 5);
159 ADD_RANGE(R300_TX_ENABLE, 1);
160 ADD_RANGE(0x4200, 4);
161 ADD_RANGE(0x4214, 1);
162 ADD_RANGE(R300_RE_POINTSIZE, 1);
163 ADD_RANGE(0x4230, 3);
164 ADD_RANGE(R300_RE_LINE_CNT, 1);
165 ADD_RANGE(0x4238, 1);
166 ADD_RANGE(0x4260, 3);
167 ADD_RANGE(0x4274, 4);
168 ADD_RANGE(0x4288, 5);
169 ADD_RANGE(0x42A0, 1);
170 ADD_RANGE(R300_RE_ZBIAS_T_FACTOR, 4);
171 ADD_RANGE(0x42B4, 1);
172 ADD_RANGE(R300_RE_CULL_CNTL, 1);
173 ADD_RANGE(0x42C0, 2);
174 ADD_RANGE(R300_RS_CNTL_0, 2);
175 ADD_RANGE(R300_RS_INTERP_0, 8);
176 ADD_RANGE(R300_RS_ROUTE_0, 8);
177 ADD_RANGE(0x43A4, 2);
178 ADD_RANGE(0x43E8, 1);
179 ADD_RANGE(R300_PFS_CNTL_0, 3);
180 ADD_RANGE(R300_PFS_NODE_0, 4);
181 ADD_RANGE(R300_PFS_TEXI_0, 64);
182 ADD_RANGE(0x46A4, 5);
183 ADD_RANGE(R300_PFS_INSTR0_0, 64);
184 ADD_RANGE(R300_PFS_INSTR1_0, 64);
185 ADD_RANGE(R300_PFS_INSTR2_0, 64);
186 ADD_RANGE(R300_PFS_INSTR3_0, 64);
187 ADD_RANGE(0x4BC0, 1);
188 ADD_RANGE(0x4BC8, 3);
189 ADD_RANGE(R300_PP_ALPHA_TEST, 2);
190 ADD_RANGE(0x4BD8, 1);
191 ADD_RANGE(R300_PFS_PARAM_0_X, 64);
192 ADD_RANGE(0x4E00, 1);
193 ADD_RANGE(R300_RB3D_CBLEND, 2);
194 ADD_RANGE(R300_RB3D_COLORMASK, 1);
195 ADD_RANGE(0x4E10, 3);
196 ADD_RANGE_MARK(R300_RB3D_COLOROFFSET0, 1, MARK_CHECK_OFFSET); /* check offset */
197 ADD_RANGE(R300_RB3D_COLORPITCH0, 1);
198 ADD_RANGE(0x4E50, 9);
199 ADD_RANGE(0x4E88, 1);
200 ADD_RANGE(0x4EA0, 2);
201 ADD_RANGE(R300_RB3D_ZSTENCIL_CNTL_0, 3);
202 ADD_RANGE(0x4F10, 4);
203 ADD_RANGE_MARK(R300_RB3D_DEPTHOFFSET, 1, MARK_CHECK_OFFSET); /* check offset */
204 ADD_RANGE(R300_RB3D_DEPTHPITCH, 1);
205 ADD_RANGE(0x4F28, 1);
206 ADD_RANGE(0x4F30, 2);
207 ADD_RANGE(0x4F44, 1);
208 ADD_RANGE(0x4F54, 1);
209
210 ADD_RANGE(R300_TX_FILTER_0, 16);
211 ADD_RANGE(R300_TX_UNK1_0, 16);
212 ADD_RANGE(R300_TX_SIZE_0, 16);
213 ADD_RANGE(R300_TX_FORMAT_0, 16);
214 /* Texture offset is dangerous and needs more checking */
215 ADD_RANGE_MARK(R300_TX_OFFSET_0, 16, MARK_CHECK_OFFSET);
216 ADD_RANGE(R300_TX_UNK4_0, 16);
217 ADD_RANGE(R300_TX_BORDER_COLOR_0, 16);
218
219 /* Sporadic registers used as primitives are emitted */
220 ADD_RANGE(0x4f18, 1);
221 ADD_RANGE(R300_RB3D_DSTCACHE_CTLSTAT, 1);
222 ADD_RANGE(R300_VAP_INPUT_ROUTE_0_0, 8);
223 ADD_RANGE(R300_VAP_INPUT_ROUTE_1_0, 8);
224
225}
226
227static __inline__ int r300_check_range(unsigned reg, int count)
228{
229 int i;
230 if(reg & ~0xffff)return -1;
231 for(i=(reg>>2);i<(reg>>2)+count;i++)
232 if(r300_reg_flags[i]!=MARK_SAFE)return 1;
233 return 0;
234}
235
236 /* we expect offsets passed to the framebuffer to be either within video memory or
237 within AGP space */
238static __inline__ int r300_check_offset(drm_radeon_private_t* dev_priv, u32 offset)
239{
240 /* we realy want to check against end of video aperture
241 but this value is not being kept.
242 This code is correct for now (does the same thing as the
243 code that sets MC_FB_LOCATION) in radeon_cp.c */
244 if((offset>=dev_priv->fb_location) &&
245 (offset<dev_priv->gart_vm_start))return 0;
246 if((offset>=dev_priv->gart_vm_start) &&
247 (offset<dev_priv->gart_vm_start+dev_priv->gart_size))return 0;
248 return 1;
249}
250
251static __inline__ int r300_emit_carefully_checked_packet0(drm_radeon_private_t* dev_priv,
252 drm_radeon_cmd_buffer_t* cmdbuf,
253 drm_r300_cmd_header_t header)
254{
255 int reg;
256 int sz;
257 int i;
258 int values[64];
259 RING_LOCALS;
260
261 sz = header.packet0.count;
262 reg = (header.packet0.reghi << 8) | header.packet0.reglo;
263
264 if((sz>64)||(sz<0)){
265 DRM_ERROR("Cannot emit more than 64 values at a time (reg=%04x sz=%d)\n", reg, sz);
266 return DRM_ERR(EINVAL);
267 }
268 for(i=0;i<sz;i++){
269 values[i]=((int __user*)cmdbuf->buf)[i];
270 switch(r300_reg_flags[(reg>>2)+i]){
271 case MARK_SAFE:
272 break;
273 case MARK_CHECK_OFFSET:
274 if(r300_check_offset(dev_priv, (u32)values[i])){
275 DRM_ERROR("Offset failed range check (reg=%04x sz=%d)\n", reg, sz);
276 return DRM_ERR(EINVAL);
277 }
278 break;
279 default:
280 DRM_ERROR("Register %04x failed check as flag=%02x\n", reg+i*4, r300_reg_flags[(reg>>2)+i]);
281 return DRM_ERR(EINVAL);
282 }
283 }
284
285 BEGIN_RING(1+sz);
286 OUT_RING( CP_PACKET0( reg, sz-1 ) );
287 OUT_RING_TABLE( values, sz );
288 ADVANCE_RING();
289
290 cmdbuf->buf += sz*4;
291 cmdbuf->bufsz -= sz*4;
292
293 return 0;
294}
295
296/**
297 * Emits a packet0 setting arbitrary registers.
298 * Called by r300_do_cp_cmdbuf.
299 *
300 * Note that checks are performed on contents and addresses of the registers
301 */
302static __inline__ int r300_emit_packet0(drm_radeon_private_t* dev_priv,
303 drm_radeon_cmd_buffer_t* cmdbuf,
304 drm_r300_cmd_header_t header)
305{
306 int reg;
307 int sz;
308 RING_LOCALS;
309
310 sz = header.packet0.count;
311 reg = (header.packet0.reghi << 8) | header.packet0.reglo;
312
313 if (!sz)
314 return 0;
315
316 if (sz*4 > cmdbuf->bufsz)
317 return DRM_ERR(EINVAL);
318
319 if (reg+sz*4 >= 0x10000){
320 DRM_ERROR("No such registers in hardware reg=%04x sz=%d\n", reg, sz);
321 return DRM_ERR(EINVAL);
322 }
323
324 if(r300_check_range(reg, sz)){
325 /* go and check everything */
326 return r300_emit_carefully_checked_packet0(dev_priv, cmdbuf, header);
327 }
328 /* the rest of the data is safe to emit, whatever the values the user passed */
329
330 BEGIN_RING(1+sz);
331 OUT_RING( CP_PACKET0( reg, sz-1 ) );
332 OUT_RING_TABLE( (int __user*)cmdbuf->buf, sz );
333 ADVANCE_RING();
334
335 cmdbuf->buf += sz*4;
336 cmdbuf->bufsz -= sz*4;
337
338 return 0;
339}
340
341
342/**
343 * Uploads user-supplied vertex program instructions or parameters onto
344 * the graphics card.
345 * Called by r300_do_cp_cmdbuf.
346 */
347static __inline__ int r300_emit_vpu(drm_radeon_private_t* dev_priv,
348 drm_radeon_cmd_buffer_t* cmdbuf,
349 drm_r300_cmd_header_t header)
350{
351 int sz;
352 int addr;
353 RING_LOCALS;
354
355 sz = header.vpu.count;
356 addr = (header.vpu.adrhi << 8) | header.vpu.adrlo;
357
358 if (!sz)
359 return 0;
360 if (sz*16 > cmdbuf->bufsz)
361 return DRM_ERR(EINVAL);
362
363 BEGIN_RING(5+sz*4);
364 /* Wait for VAP to come to senses.. */
365 /* there is no need to emit it multiple times, (only once before VAP is programmed,
366 but this optimization is for later */
367 OUT_RING_REG( R300_VAP_PVS_WAITIDLE, 0 );
368 OUT_RING_REG( R300_VAP_PVS_UPLOAD_ADDRESS, addr );
369 OUT_RING( CP_PACKET0_TABLE( R300_VAP_PVS_UPLOAD_DATA, sz*4 - 1 ) );
370 OUT_RING_TABLE( (int __user*)cmdbuf->buf, sz*4 );
371
372 ADVANCE_RING();
373
374 cmdbuf->buf += sz*16;
375 cmdbuf->bufsz -= sz*16;
376
377 return 0;
378}
379
380
381/**
382 * Emit a clear packet from userspace.
383 * Called by r300_emit_packet3.
384 */
385static __inline__ int r300_emit_clear(drm_radeon_private_t* dev_priv,
386 drm_radeon_cmd_buffer_t* cmdbuf)
387{
388 RING_LOCALS;
389
390 if (8*4 > cmdbuf->bufsz)
391 return DRM_ERR(EINVAL);
392
393 BEGIN_RING(10);
394 OUT_RING( CP_PACKET3( R200_3D_DRAW_IMMD_2, 8 ) );
395 OUT_RING( R300_PRIM_TYPE_POINT|R300_PRIM_WALK_RING|
396 (1<<R300_PRIM_NUM_VERTICES_SHIFT) );
397 OUT_RING_TABLE( (int __user*)cmdbuf->buf, 8 );
398 ADVANCE_RING();
399
400 cmdbuf->buf += 8*4;
401 cmdbuf->bufsz -= 8*4;
402
403 return 0;
404}
405
406static __inline__ int r300_emit_3d_load_vbpntr(drm_radeon_private_t* dev_priv,
407 drm_radeon_cmd_buffer_t* cmdbuf,
408 u32 header)
409{
410 int count, i,k;
411 #define MAX_ARRAY_PACKET 64
412 u32 payload[MAX_ARRAY_PACKET];
413 u32 narrays;
414 RING_LOCALS;
415
416 count=(header>>16) & 0x3fff;
417
418 if((count+1)>MAX_ARRAY_PACKET){
419 DRM_ERROR("Too large payload in 3D_LOAD_VBPNTR (count=%d)\n", count);
420 return DRM_ERR(EINVAL);
421 }
422 memset(payload, 0, MAX_ARRAY_PACKET*4);
423 memcpy(payload, cmdbuf->buf+4, (count+1)*4);
424
425 /* carefully check packet contents */
426
427 narrays=payload[0];
428 k=0;
429 i=1;
430 while((k<narrays) && (i<(count+1))){
431 i++; /* skip attribute field */
432 if(r300_check_offset(dev_priv, payload[i])){
433 DRM_ERROR("Offset failed range check (k=%d i=%d) while processing 3D_LOAD_VBPNTR packet.\n", k, i);
434 return DRM_ERR(EINVAL);
435 }
436 k++;
437 i++;
438 if(k==narrays)break;
439 /* have one more to process, they come in pairs */
440 if(r300_check_offset(dev_priv, payload[i])){
441 DRM_ERROR("Offset failed range check (k=%d i=%d) while processing 3D_LOAD_VBPNTR packet.\n", k, i);
442 return DRM_ERR(EINVAL);
443 }
444 k++;
445 i++;
446 }
447 /* do the counts match what we expect ? */
448 if((k!=narrays) || (i!=(count+1))){
449 DRM_ERROR("Malformed 3D_LOAD_VBPNTR packet (k=%d i=%d narrays=%d count+1=%d).\n", k, i, narrays, count+1);
450 return DRM_ERR(EINVAL);
451 }
452
453 /* all clear, output packet */
454
455 BEGIN_RING(count+2);
456 OUT_RING(header);
457 OUT_RING_TABLE(payload, count+1);
458 ADVANCE_RING();
459
460 cmdbuf->buf += (count+2)*4;
461 cmdbuf->bufsz -= (count+2)*4;
462
463 return 0;
464}
465
466static __inline__ int r300_emit_raw_packet3(drm_radeon_private_t* dev_priv,
467 drm_radeon_cmd_buffer_t* cmdbuf)
468{
469 u32 header;
470 int count;
471 RING_LOCALS;
472
473 if (4 > cmdbuf->bufsz)
474 return DRM_ERR(EINVAL);
475
476 /* Fixme !! This simply emits a packet without much checking.
477 We need to be smarter. */
478
479 /* obtain first word - actual packet3 header */
480 header = *(u32 __user*)cmdbuf->buf;
481
482 /* Is it packet 3 ? */
483 if( (header>>30)!=0x3 ) {
484 DRM_ERROR("Not a packet3 header (0x%08x)\n", header);
485 return DRM_ERR(EINVAL);
486 }
487
488 count=(header>>16) & 0x3fff;
489
490 /* Check again now that we know how much data to expect */
491 if ((count+2)*4 > cmdbuf->bufsz){
492 DRM_ERROR("Expected packet3 of length %d but have only %d bytes left\n",
493 (count+2)*4, cmdbuf->bufsz);
494 return DRM_ERR(EINVAL);
495 }
496
497 /* Is it a packet type we know about ? */
498 switch(header & 0xff00){
499 case RADEON_3D_LOAD_VBPNTR: /* load vertex array pointers */
500 return r300_emit_3d_load_vbpntr(dev_priv, cmdbuf, header);
501
502 case RADEON_CP_3D_DRAW_IMMD_2: /* triggers drawing using in-packet vertex data */
503 case RADEON_CP_3D_DRAW_VBUF_2: /* triggers drawing of vertex buffers setup elsewhere */
504 case RADEON_CP_3D_DRAW_INDX_2: /* triggers drawing using indices to vertex buffer */
505 case RADEON_CP_INDX_BUFFER: /* DRAW_INDX_2 without INDX_BUFFER seems to lock up the gpu */
506 case RADEON_WAIT_FOR_IDLE:
507 case RADEON_CP_NOP:
508 /* these packets are safe */
509 break;
510 default:
511 DRM_ERROR("Unknown packet3 header (0x%08x)\n", header);
512 return DRM_ERR(EINVAL);
513 }
514
515
516 BEGIN_RING(count+2);
517 OUT_RING(header);
518 OUT_RING_TABLE( (int __user*)(cmdbuf->buf+4), count+1);
519 ADVANCE_RING();
520
521 cmdbuf->buf += (count+2)*4;
522 cmdbuf->bufsz -= (count+2)*4;
523
524 return 0;
525}
526
527
528/**
529 * Emit a rendering packet3 from userspace.
530 * Called by r300_do_cp_cmdbuf.
531 */
532static __inline__ int r300_emit_packet3(drm_radeon_private_t* dev_priv,
533 drm_radeon_cmd_buffer_t* cmdbuf,
534 drm_r300_cmd_header_t header)
535{
536 int n;
537 int ret;
538 char __user* orig_buf = cmdbuf->buf;
539 int orig_bufsz = cmdbuf->bufsz;
540
541 /* This is a do-while-loop so that we run the interior at least once,
542 * even if cmdbuf->nbox is 0. Compare r300_emit_cliprects for rationale.
543 */
544 n = 0;
545 do {
546 if (cmdbuf->nbox > R300_SIMULTANEOUS_CLIPRECTS) {
547 ret = r300_emit_cliprects(dev_priv, cmdbuf, n);
548 if (ret)
549 return ret;
550
551 cmdbuf->buf = orig_buf;
552 cmdbuf->bufsz = orig_bufsz;
553 }
554
555 switch(header.packet3.packet) {
556 case R300_CMD_PACKET3_CLEAR:
557 DRM_DEBUG("R300_CMD_PACKET3_CLEAR\n");
558 ret = r300_emit_clear(dev_priv, cmdbuf);
559 if (ret) {
560 DRM_ERROR("r300_emit_clear failed\n");
561 return ret;
562 }
563 break;
564
565 case R300_CMD_PACKET3_RAW:
566 DRM_DEBUG("R300_CMD_PACKET3_RAW\n");
567 ret = r300_emit_raw_packet3(dev_priv, cmdbuf);
568 if (ret) {
569 DRM_ERROR("r300_emit_raw_packet3 failed\n");
570 return ret;
571 }
572 break;
573
574 default:
575 DRM_ERROR("bad packet3 type %i at %p\n",
576 header.packet3.packet,
577 cmdbuf->buf - sizeof(header));
578 return DRM_ERR(EINVAL);
579 }
580
581 n += R300_SIMULTANEOUS_CLIPRECTS;
582 } while(n < cmdbuf->nbox);
583
584 return 0;
585}
586
587/* Some of the R300 chips seem to be extremely touchy about the two registers
588 * that are configured in r300_pacify.
589 * Among the worst offenders seems to be the R300 ND (0x4E44): When userspace
590 * sends a command buffer that contains only state setting commands and a
591 * vertex program/parameter upload sequence, this will eventually lead to a
592 * lockup, unless the sequence is bracketed by calls to r300_pacify.
593 * So we should take great care to *always* call r300_pacify before
594 * *anything* 3D related, and again afterwards. This is what the
595 * call bracket in r300_do_cp_cmdbuf is for.
596 */
597
598/**
599 * Emit the sequence to pacify R300.
600 */
601static __inline__ void r300_pacify(drm_radeon_private_t* dev_priv)
602{
603 RING_LOCALS;
604
605 BEGIN_RING(6);
606 OUT_RING( CP_PACKET0( R300_RB3D_DSTCACHE_CTLSTAT, 0 ) );
607 OUT_RING( 0xa );
608 OUT_RING( CP_PACKET0( 0x4f18, 0 ) );
609 OUT_RING( 0x3 );
610 OUT_RING( CP_PACKET3( RADEON_CP_NOP, 0 ) );
611 OUT_RING( 0x0 );
612 ADVANCE_RING();
613}
614
615
616/**
617 * Called by r300_do_cp_cmdbuf to update the internal buffer age and state.
618 * The actual age emit is done by r300_do_cp_cmdbuf, which is why you must
619 * be careful about how this function is called.
620 */
621static void r300_discard_buffer(drm_device_t * dev, drm_buf_t * buf)
622{
623 drm_radeon_private_t *dev_priv = dev->dev_private;
624 drm_radeon_buf_priv_t *buf_priv = buf->dev_private;
625
626 buf_priv->age = ++dev_priv->sarea_priv->last_dispatch;
627 buf->pending = 1;
628 buf->used = 0;
629}
630
631
632/**
633 * Parses and validates a user-supplied command buffer and emits appropriate
634 * commands on the DMA ring buffer.
635 * Called by the ioctl handler function radeon_cp_cmdbuf.
636 */
637int r300_do_cp_cmdbuf(drm_device_t* dev,
638 DRMFILE filp,
639 drm_file_t* filp_priv,
640 drm_radeon_cmd_buffer_t* cmdbuf)
641{
642 drm_radeon_private_t *dev_priv = dev->dev_private;
643 drm_device_dma_t *dma = dev->dma;
644 drm_buf_t *buf = NULL;
645 int emit_dispatch_age = 0;
646 int ret = 0;
647
648 DRM_DEBUG("\n");
649
650 /* See the comment above r300_emit_begin3d for why this call must be here,
651 * and what the cleanup gotos are for. */
652 r300_pacify(dev_priv);
653
654 if (cmdbuf->nbox <= R300_SIMULTANEOUS_CLIPRECTS) {
655 ret = r300_emit_cliprects(dev_priv, cmdbuf, 0);
656 if (ret)
657 goto cleanup;
658 }
659
660 while(cmdbuf->bufsz >= sizeof(drm_r300_cmd_header_t)) {
661 int idx;
662 drm_r300_cmd_header_t header;
663
664 header.u = *(unsigned int *)cmdbuf->buf;
665
666 cmdbuf->buf += sizeof(header);
667 cmdbuf->bufsz -= sizeof(header);
668
669 switch(header.header.cmd_type) {
670 case R300_CMD_PACKET0:
671 DRM_DEBUG("R300_CMD_PACKET0\n");
672 ret = r300_emit_packet0(dev_priv, cmdbuf, header);
673 if (ret) {
674 DRM_ERROR("r300_emit_packet0 failed\n");
675 goto cleanup;
676 }
677 break;
678
679 case R300_CMD_VPU:
680 DRM_DEBUG("R300_CMD_VPU\n");
681 ret = r300_emit_vpu(dev_priv, cmdbuf, header);
682 if (ret) {
683 DRM_ERROR("r300_emit_vpu failed\n");
684 goto cleanup;
685 }
686 break;
687
688 case R300_CMD_PACKET3:
689 DRM_DEBUG("R300_CMD_PACKET3\n");
690 ret = r300_emit_packet3(dev_priv, cmdbuf, header);
691 if (ret) {
692 DRM_ERROR("r300_emit_packet3 failed\n");
693 goto cleanup;
694 }
695 break;
696
697 case R300_CMD_END3D:
698 DRM_DEBUG("R300_CMD_END3D\n");
699 /* TODO:
700 Ideally userspace driver should not need to issue this call,
701 i.e. the drm driver should issue it automatically and prevent
702 lockups.
703
704 In practice, we do not understand why this call is needed and what
705 it does (except for some vague guesses that it has to do with cache
706 coherence) and so the user space driver does it.
707
708 Once we are sure which uses prevent lockups the code could be moved
709 into the kernel and the userspace driver will not
710 need to use this command.
711
712 Note that issuing this command does not hurt anything
713 except, possibly, performance */
714 r300_pacify(dev_priv);
715 break;
716
717 case R300_CMD_CP_DELAY:
718 /* simple enough, we can do it here */
719 DRM_DEBUG("R300_CMD_CP_DELAY\n");
720 {
721 int i;
722 RING_LOCALS;
723
724 BEGIN_RING(header.delay.count);
725 for(i=0;i<header.delay.count;i++)
726 OUT_RING(RADEON_CP_PACKET2);
727 ADVANCE_RING();
728 }
729 break;
730
731 case R300_CMD_DMA_DISCARD:
732 DRM_DEBUG("RADEON_CMD_DMA_DISCARD\n");
733 idx = header.dma.buf_idx;
734 if (idx < 0 || idx >= dma->buf_count) {
735 DRM_ERROR("buffer index %d (of %d max)\n",
736 idx, dma->buf_count - 1);
737 ret = DRM_ERR(EINVAL);
738 goto cleanup;
739 }
740
741 buf = dma->buflist[idx];
742 if (buf->filp != filp || buf->pending) {
743 DRM_ERROR("bad buffer %p %p %d\n",
744 buf->filp, filp, buf->pending);
745 ret = DRM_ERR(EINVAL);
746 goto cleanup;
747 }
748
749 emit_dispatch_age = 1;
750 r300_discard_buffer(dev, buf);
751 break;
752
753 case R300_CMD_WAIT:
754 /* simple enough, we can do it here */
755 DRM_DEBUG("R300_CMD_WAIT\n");
756 if(header.wait.flags==0)break; /* nothing to do */
757
758 {
759 RING_LOCALS;
760
761 BEGIN_RING(2);
762 OUT_RING( CP_PACKET0( RADEON_WAIT_UNTIL, 0 ) );
763 OUT_RING( (header.wait.flags & 0xf)<<14 );
764 ADVANCE_RING();
765 }
766 break;
767
768 default:
769 DRM_ERROR("bad cmd_type %i at %p\n",
770 header.header.cmd_type,
771 cmdbuf->buf - sizeof(header));
772 ret = DRM_ERR(EINVAL);
773 goto cleanup;
774 }
775 }
776
777 DRM_DEBUG("END\n");
778
779cleanup:
780 r300_pacify(dev_priv);
781
782 /* We emit the vertex buffer age here, outside the pacifier "brackets"
783 * for two reasons:
784 * (1) This may coalesce multiple age emissions into a single one and
785 * (2) more importantly, some chips lock up hard when scratch registers
786 * are written inside the pacifier bracket.
787 */
788 if (emit_dispatch_age) {
789 RING_LOCALS;
790
791 /* Emit the vertex buffer age */
792 BEGIN_RING(2);
793 RADEON_DISPATCH_AGE(dev_priv->sarea_priv->last_dispatch);
794 ADVANCE_RING();
795 }
796
797 COMMIT_RING();
798
799 return ret;
800}
801
diff --git a/drivers/char/drm/r300_reg.h b/drivers/char/drm/r300_reg.h
new file mode 100644
index 000000000000..c3e7ca3dbe3d
--- /dev/null
+++ b/drivers/char/drm/r300_reg.h
@@ -0,0 +1,1412 @@
1/**************************************************************************
2
3Copyright (C) 2004-2005 Nicolai Haehnle et al.
4
5Permission is hereby granted, free of charge, to any person obtaining a
6copy of this software and associated documentation files (the "Software"),
7to deal in the Software without restriction, including without limitation
8on the rights to use, copy, modify, merge, publish, distribute, sub
9license, and/or sell copies of the Software, and to permit persons to whom
10the Software is furnished to do so, subject to the following conditions:
11
12The above copyright notice and this permission notice (including the next
13paragraph) shall be included in all copies or substantial portions of the
14Software.
15
16THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL
19THE AUTHOR(S) AND/OR THEIR SUPPLIERS BE LIABLE FOR ANY CLAIM,
20DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
21OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
22USE OR OTHER DEALINGS IN THE SOFTWARE.
23
24**************************************************************************/
25
26#ifndef _R300_REG_H
27#define _R300_REG_H
28
29#define R300_MC_INIT_MISC_LAT_TIMER 0x180
30# define R300_MC_MISC__MC_CPR_INIT_LAT_SHIFT 0
31# define R300_MC_MISC__MC_VF_INIT_LAT_SHIFT 4
32# define R300_MC_MISC__MC_DISP0R_INIT_LAT_SHIFT 8
33# define R300_MC_MISC__MC_DISP1R_INIT_LAT_SHIFT 12
34# define R300_MC_MISC__MC_FIXED_INIT_LAT_SHIFT 16
35# define R300_MC_MISC__MC_E2R_INIT_LAT_SHIFT 20
36# define R300_MC_MISC__MC_SAME_PAGE_PRIO_SHIFT 24
37# define R300_MC_MISC__MC_GLOBW_INIT_LAT_SHIFT 28
38
39
40#define R300_MC_INIT_GFX_LAT_TIMER 0x154
41# define R300_MC_MISC__MC_G3D0R_INIT_LAT_SHIFT 0
42# define R300_MC_MISC__MC_G3D1R_INIT_LAT_SHIFT 4
43# define R300_MC_MISC__MC_G3D2R_INIT_LAT_SHIFT 8
44# define R300_MC_MISC__MC_G3D3R_INIT_LAT_SHIFT 12
45# define R300_MC_MISC__MC_TX0R_INIT_LAT_SHIFT 16
46# define R300_MC_MISC__MC_TX1R_INIT_LAT_SHIFT 20
47# define R300_MC_MISC__MC_GLOBR_INIT_LAT_SHIFT 24
48# define R300_MC_MISC__MC_GLOBW_FULL_LAT_SHIFT 28
49
50/*
51This file contains registers and constants for the R300. They have been
52found mostly by examining command buffers captured using glxtest, as well
53as by extrapolating some known registers and constants from the R200.
54
55I am fairly certain that they are correct unless stated otherwise in comments.
56*/
57
58#define R300_SE_VPORT_XSCALE 0x1D98
59#define R300_SE_VPORT_XOFFSET 0x1D9C
60#define R300_SE_VPORT_YSCALE 0x1DA0
61#define R300_SE_VPORT_YOFFSET 0x1DA4
62#define R300_SE_VPORT_ZSCALE 0x1DA8
63#define R300_SE_VPORT_ZOFFSET 0x1DAC
64
65
66/* This register is written directly and also starts data section in many 3d CP_PACKET3's */
67#define R300_VAP_VF_CNTL 0x2084
68
69# define R300_VAP_VF_CNTL__PRIM_TYPE__SHIFT 0
70# define R300_VAP_VF_CNTL__PRIM_NONE (0<<0)
71# define R300_VAP_VF_CNTL__PRIM_POINTS (1<<0)
72# define R300_VAP_VF_CNTL__PRIM_LINES (2<<0)
73# define R300_VAP_VF_CNTL__PRIM_LINE_STRIP (3<<0)
74# define R300_VAP_VF_CNTL__PRIM_TRIANGLES (4<<0)
75# define R300_VAP_VF_CNTL__PRIM_TRIANGLE_FAN (5<<0)
76# define R300_VAP_VF_CNTL__PRIM_TRIANGLE_STRIP (6<<0)
77# define R300_VAP_VF_CNTL__PRIM_LINE_LOOP (12<<0)
78# define R300_VAP_VF_CNTL__PRIM_QUADS (13<<0)
79# define R300_VAP_VF_CNTL__PRIM_QUAD_STRIP (14<<0)
80# define R300_VAP_VF_CNTL__PRIM_POLYGON (15<<0)
81
82# define R300_VAP_VF_CNTL__PRIM_WALK__SHIFT 4
83 /* State based - direct writes to registers trigger vertex generation */
84# define R300_VAP_VF_CNTL__PRIM_WALK_STATE_BASED (0<<4)
85# define R300_VAP_VF_CNTL__PRIM_WALK_INDICES (1<<4)
86# define R300_VAP_VF_CNTL__PRIM_WALK_VERTEX_LIST (2<<4)
87# define R300_VAP_VF_CNTL__PRIM_WALK_VERTEX_EMBEDDED (3<<4)
88
89 /* I don't think I saw these three used.. */
90# define R300_VAP_VF_CNTL__COLOR_ORDER__SHIFT 6
91# define R300_VAP_VF_CNTL__TCL_OUTPUT_CTL_ENA__SHIFT 9
92# define R300_VAP_VF_CNTL__PROG_STREAM_ENA__SHIFT 10
93
94 /* index size - when not set the indices are assumed to be 16 bit */
95# define R300_VAP_VF_CNTL__INDEX_SIZE_32bit (1<<11)
96 /* number of vertices */
97# define R300_VAP_VF_CNTL__NUM_VERTICES__SHIFT 16
98
99/* BEGIN: Wild guesses */
100#define R300_VAP_OUTPUT_VTX_FMT_0 0x2090
101# define R300_VAP_OUTPUT_VTX_FMT_0__POS_PRESENT (1<<0)
102# define R300_VAP_OUTPUT_VTX_FMT_0__COLOR_PRESENT (1<<1)
103# define R300_VAP_OUTPUT_VTX_FMT_0__COLOR_1_PRESENT (1<<2) /* GUESS */
104# define R300_VAP_OUTPUT_VTX_FMT_0__COLOR_2_PRESENT (1<<3) /* GUESS */
105# define R300_VAP_OUTPUT_VTX_FMT_0__COLOR_3_PRESENT (1<<4) /* GUESS */
106# define R300_VAP_OUTPUT_VTX_FMT_0__PT_SIZE_PRESENT (1<<16) /* GUESS */
107
108#define R300_VAP_OUTPUT_VTX_FMT_1 0x2094
109# define R300_VAP_OUTPUT_VTX_FMT_1__TEX_0_COMP_CNT_SHIFT 0
110# define R300_VAP_OUTPUT_VTX_FMT_1__TEX_1_COMP_CNT_SHIFT 3
111# define R300_VAP_OUTPUT_VTX_FMT_1__TEX_2_COMP_CNT_SHIFT 6
112# define R300_VAP_OUTPUT_VTX_FMT_1__TEX_3_COMP_CNT_SHIFT 9
113# define R300_VAP_OUTPUT_VTX_FMT_1__TEX_4_COMP_CNT_SHIFT 12
114# define R300_VAP_OUTPUT_VTX_FMT_1__TEX_5_COMP_CNT_SHIFT 15
115# define R300_VAP_OUTPUT_VTX_FMT_1__TEX_6_COMP_CNT_SHIFT 18
116# define R300_VAP_OUTPUT_VTX_FMT_1__TEX_7_COMP_CNT_SHIFT 21
117/* END */
118
119#define R300_SE_VTE_CNTL 0x20b0
120# define R300_VPORT_X_SCALE_ENA 0x00000001
121# define R300_VPORT_X_OFFSET_ENA 0x00000002
122# define R300_VPORT_Y_SCALE_ENA 0x00000004
123# define R300_VPORT_Y_OFFSET_ENA 0x00000008
124# define R300_VPORT_Z_SCALE_ENA 0x00000010
125# define R300_VPORT_Z_OFFSET_ENA 0x00000020
126# define R300_VTX_XY_FMT 0x00000100
127# define R300_VTX_Z_FMT 0x00000200
128# define R300_VTX_W0_FMT 0x00000400
129# define R300_VTX_W0_NORMALIZE 0x00000800
130# define R300_VTX_ST_DENORMALIZED 0x00001000
131
132/* BEGIN: Vertex data assembly - lots of uncertainties */
133/* gap */
134/* Where do we get our vertex data?
135//
136// Vertex data either comes either from immediate mode registers or from
137// vertex arrays.
138// There appears to be no mixed mode (though we can force the pitch of
139// vertex arrays to 0, effectively reusing the same element over and over
140// again).
141//
142// Immediate mode is controlled by the INPUT_CNTL registers. I am not sure
143// if these registers influence vertex array processing.
144//
145// Vertex arrays are controlled via the 3D_LOAD_VBPNTR packet3.
146//
147// In both cases, vertex attributes are then passed through INPUT_ROUTE.
148
149// Beginning with INPUT_ROUTE_0_0 is a list of WORDs that route vertex data
150// into the vertex processor's input registers.
151// The first word routes the first input, the second word the second, etc.
152// The corresponding input is routed into the register with the given index.
153// The list is ended by a word with INPUT_ROUTE_END set.
154//
155// Always set COMPONENTS_4 in immediate mode. */
156
157#define R300_VAP_INPUT_ROUTE_0_0 0x2150
158# define R300_INPUT_ROUTE_COMPONENTS_1 (0 << 0)
159# define R300_INPUT_ROUTE_COMPONENTS_2 (1 << 0)
160# define R300_INPUT_ROUTE_COMPONENTS_3 (2 << 0)
161# define R300_INPUT_ROUTE_COMPONENTS_4 (3 << 0)
162# define R300_INPUT_ROUTE_COMPONENTS_RGBA (4 << 0) /* GUESS */
163# define R300_VAP_INPUT_ROUTE_IDX_SHIFT 8
164# define R300_VAP_INPUT_ROUTE_IDX_MASK (31 << 8) /* GUESS */
165# define R300_VAP_INPUT_ROUTE_END (1 << 13)
166# define R300_INPUT_ROUTE_IMMEDIATE_MODE (0 << 14) /* GUESS */
167# define R300_INPUT_ROUTE_FLOAT (1 << 14) /* GUESS */
168# define R300_INPUT_ROUTE_UNSIGNED_BYTE (2 << 14) /* GUESS */
169# define R300_INPUT_ROUTE_FLOAT_COLOR (3 << 14) /* GUESS */
170#define R300_VAP_INPUT_ROUTE_0_1 0x2154
171#define R300_VAP_INPUT_ROUTE_0_2 0x2158
172#define R300_VAP_INPUT_ROUTE_0_3 0x215C
173#define R300_VAP_INPUT_ROUTE_0_4 0x2160
174#define R300_VAP_INPUT_ROUTE_0_5 0x2164
175#define R300_VAP_INPUT_ROUTE_0_6 0x2168
176#define R300_VAP_INPUT_ROUTE_0_7 0x216C
177
178/* gap */
179/* Notes:
180// - always set up to produce at least two attributes:
181// if vertex program uses only position, fglrx will set normal, too
182// - INPUT_CNTL_0_COLOR and INPUT_CNTL_COLOR bits are always equal */
183#define R300_VAP_INPUT_CNTL_0 0x2180
184# define R300_INPUT_CNTL_0_COLOR 0x00000001
185#define R300_VAP_INPUT_CNTL_1 0x2184
186# define R300_INPUT_CNTL_POS 0x00000001
187# define R300_INPUT_CNTL_NORMAL 0x00000002
188# define R300_INPUT_CNTL_COLOR 0x00000004
189# define R300_INPUT_CNTL_TC0 0x00000400
190# define R300_INPUT_CNTL_TC1 0x00000800
191# define R300_INPUT_CNTL_TC2 0x00001000 /* GUESS */
192# define R300_INPUT_CNTL_TC3 0x00002000 /* GUESS */
193# define R300_INPUT_CNTL_TC4 0x00004000 /* GUESS */
194# define R300_INPUT_CNTL_TC5 0x00008000 /* GUESS */
195# define R300_INPUT_CNTL_TC6 0x00010000 /* GUESS */
196# define R300_INPUT_CNTL_TC7 0x00020000 /* GUESS */
197
198/* gap */
199/* Words parallel to INPUT_ROUTE_0; All words that are active in INPUT_ROUTE_0
200// are set to a swizzling bit pattern, other words are 0.
201//
202// In immediate mode, the pattern is always set to xyzw. In vertex array
203// mode, the swizzling pattern is e.g. used to set zw components in texture
204// coordinates with only tweo components. */
205#define R300_VAP_INPUT_ROUTE_1_0 0x21E0
206# define R300_INPUT_ROUTE_SELECT_X 0
207# define R300_INPUT_ROUTE_SELECT_Y 1
208# define R300_INPUT_ROUTE_SELECT_Z 2
209# define R300_INPUT_ROUTE_SELECT_W 3
210# define R300_INPUT_ROUTE_SELECT_ZERO 4
211# define R300_INPUT_ROUTE_SELECT_ONE 5
212# define R300_INPUT_ROUTE_SELECT_MASK 7
213# define R300_INPUT_ROUTE_X_SHIFT 0
214# define R300_INPUT_ROUTE_Y_SHIFT 3
215# define R300_INPUT_ROUTE_Z_SHIFT 6
216# define R300_INPUT_ROUTE_W_SHIFT 9
217# define R300_INPUT_ROUTE_ENABLE (15 << 12)
218#define R300_VAP_INPUT_ROUTE_1_1 0x21E4
219#define R300_VAP_INPUT_ROUTE_1_2 0x21E8
220#define R300_VAP_INPUT_ROUTE_1_3 0x21EC
221#define R300_VAP_INPUT_ROUTE_1_4 0x21F0
222#define R300_VAP_INPUT_ROUTE_1_5 0x21F4
223#define R300_VAP_INPUT_ROUTE_1_6 0x21F8
224#define R300_VAP_INPUT_ROUTE_1_7 0x21FC
225
226/* END */
227
228/* gap */
229/* BEGIN: Upload vertex program and data
230// The programmable vertex shader unit has a memory bank of unknown size
231// that can be written to in 16 byte units by writing the address into
232// UPLOAD_ADDRESS, followed by data in UPLOAD_DATA (multiples of 4 DWORDs).
233//
234// Pointers into the memory bank are always in multiples of 16 bytes.
235//
236// The memory bank is divided into areas with fixed meaning.
237//
238// Starting at address UPLOAD_PROGRAM: Vertex program instructions.
239// Native limits reported by drivers from ATI suggest size 256 (i.e. 4KB),
240// whereas the difference between known addresses suggests size 512.
241//
242// Starting at address UPLOAD_PARAMETERS: Vertex program parameters.
243// Native reported limits and the VPI layout suggest size 256, whereas
244// difference between known addresses suggests size 512.
245//
246// At address UPLOAD_POINTSIZE is a vector (0, 0, ps, 0), where ps is the
247// floating point pointsize. The exact purpose of this state is uncertain,
248// as there is also the R300_RE_POINTSIZE register.
249//
250// Multiple vertex programs and parameter sets can be loaded at once,
251// which could explain the size discrepancy. */
252#define R300_VAP_PVS_UPLOAD_ADDRESS 0x2200
253# define R300_PVS_UPLOAD_PROGRAM 0x00000000
254# define R300_PVS_UPLOAD_PARAMETERS 0x00000200
255# define R300_PVS_UPLOAD_POINTSIZE 0x00000406
256/* gap */
257#define R300_VAP_PVS_UPLOAD_DATA 0x2208
258/* END */
259
260/* gap */
261/* I do not know the purpose of this register. However, I do know that
262// it is set to 221C_CLEAR for clear operations and to 221C_NORMAL
263// for normal rendering. */
264#define R300_VAP_UNKNOWN_221C 0x221C
265# define R300_221C_NORMAL 0x00000000
266# define R300_221C_CLEAR 0x0001C000
267
268/* gap */
269/* Sometimes, END_OF_PKT and 0x2284=0 are the only commands sent between
270// rendering commands and overwriting vertex program parameters.
271// Therefore, I suspect writing zero to 0x2284 synchronizes the engine and
272// avoids bugs caused by still running shaders reading bad data from memory. */
273#define R300_VAP_PVS_WAITIDLE 0x2284 /* GUESS */
274
275/* Absolutely no clue what this register is about. */
276#define R300_VAP_UNKNOWN_2288 0x2288
277# define R300_2288_R300 0x00750000 /* -- nh */
278# define R300_2288_RV350 0x0000FFFF /* -- Vladimir */
279
280/* gap */
281/* Addresses are relative to the vertex program instruction area of the
282// memory bank. PROGRAM_END points to the last instruction of the active
283// program
284//
285// The meaning of the two UNKNOWN fields is obviously not known. However,
286// experiments so far have shown that both *must* point to an instruction
287// inside the vertex program, otherwise the GPU locks up.
288// fglrx usually sets CNTL_3_UNKNOWN to the end of the program and
289// CNTL_1_UNKNOWN points to instruction where last write to position takes place.
290// Most likely this is used to ignore rest of the program in cases where group of verts arent visible.
291// For some reason this "section" is sometimes accepted other instruction that have
292// no relationship with position calculations.
293*/
294#define R300_VAP_PVS_CNTL_1 0x22D0
295# define R300_PVS_CNTL_1_PROGRAM_START_SHIFT 0
296# define R300_PVS_CNTL_1_POS_END_SHIFT 10
297# define R300_PVS_CNTL_1_PROGRAM_END_SHIFT 20
298/* Addresses are relative the the vertex program parameters area. */
299#define R300_VAP_PVS_CNTL_2 0x22D4
300# define R300_PVS_CNTL_2_PARAM_OFFSET_SHIFT 0
301# define R300_PVS_CNTL_2_PARAM_COUNT_SHIFT 16
302#define R300_VAP_PVS_CNTL_3 0x22D8
303# define R300_PVS_CNTL_3_PROGRAM_UNKNOWN_SHIFT 10
304# define R300_PVS_CNTL_3_PROGRAM_UNKNOWN2_SHIFT 0
305
306/* The entire range from 0x2300 to 0x2AC inclusive seems to be used for
307// immediate vertices */
308#define R300_VAP_VTX_COLOR_R 0x2464
309#define R300_VAP_VTX_COLOR_G 0x2468
310#define R300_VAP_VTX_COLOR_B 0x246C
311#define R300_VAP_VTX_POS_0_X_1 0x2490 /* used for glVertex2*() */
312#define R300_VAP_VTX_POS_0_Y_1 0x2494
313#define R300_VAP_VTX_COLOR_PKD 0x249C /* RGBA */
314#define R300_VAP_VTX_POS_0_X_2 0x24A0 /* used for glVertex3*() */
315#define R300_VAP_VTX_POS_0_Y_2 0x24A4
316#define R300_VAP_VTX_POS_0_Z_2 0x24A8
317#define R300_VAP_VTX_END_OF_PKT 0x24AC /* write 0 to indicate end of packet? */
318
319/* gap */
320
321/* These are values from r300_reg/r300_reg.h - they are known to be correct
322 and are here so we can use one register file instead of several
323 - Vladimir */
324#define R300_GB_VAP_RASTER_VTX_FMT_0 0x4000
325# define R300_GB_VAP_RASTER_VTX_FMT_0__POS_PRESENT (1<<0)
326# define R300_GB_VAP_RASTER_VTX_FMT_0__COLOR_0_PRESENT (1<<1)
327# define R300_GB_VAP_RASTER_VTX_FMT_0__COLOR_1_PRESENT (1<<2)
328# define R300_GB_VAP_RASTER_VTX_FMT_0__COLOR_2_PRESENT (1<<3)
329# define R300_GB_VAP_RASTER_VTX_FMT_0__COLOR_3_PRESENT (1<<4)
330# define R300_GB_VAP_RASTER_VTX_FMT_0__COLOR_SPACE (0xf<<5)
331# define R300_GB_VAP_RASTER_VTX_FMT_0__PT_SIZE_PRESENT (0x1<<16)
332
333#define R300_GB_VAP_RASTER_VTX_FMT_1 0x4004
334 /* each of the following is 3 bits wide, specifies number
335 of components */
336# define R300_GB_VAP_RASTER_VTX_FMT_1__TEX_0_COMP_CNT_SHIFT 0
337# define R300_GB_VAP_RASTER_VTX_FMT_1__TEX_1_COMP_CNT_SHIFT 3
338# define R300_GB_VAP_RASTER_VTX_FMT_1__TEX_2_COMP_CNT_SHIFT 6
339# define R300_GB_VAP_RASTER_VTX_FMT_1__TEX_3_COMP_CNT_SHIFT 9
340# define R300_GB_VAP_RASTER_VTX_FMT_1__TEX_4_COMP_CNT_SHIFT 12
341# define R300_GB_VAP_RASTER_VTX_FMT_1__TEX_5_COMP_CNT_SHIFT 15
342# define R300_GB_VAP_RASTER_VTX_FMT_1__TEX_6_COMP_CNT_SHIFT 18
343# define R300_GB_VAP_RASTER_VTX_FMT_1__TEX_7_COMP_CNT_SHIFT 21
344
345/* UNK30 seems to enables point to quad transformation on textures
346 (or something closely related to that).
347 This bit is rather fatal at the time being due to lackings at pixel shader side */
348#define R300_GB_ENABLE 0x4008
349# define R300_GB_POINT_STUFF_ENABLE (1<<0)
350# define R300_GB_LINE_STUFF_ENABLE (1<<1)
351# define R300_GB_TRIANGLE_STUFF_ENABLE (1<<2)
352# define R300_GB_STENCIL_AUTO_ENABLE (1<<4)
353# define R300_GB_UNK30 (1<<30)
354 /* each of the following is 2 bits wide */
355#define R300_GB_TEX_REPLICATE 0
356#define R300_GB_TEX_ST 1
357#define R300_GB_TEX_STR 2
358# define R300_GB_TEX0_SOURCE_SHIFT 16
359# define R300_GB_TEX1_SOURCE_SHIFT 18
360# define R300_GB_TEX2_SOURCE_SHIFT 20
361# define R300_GB_TEX3_SOURCE_SHIFT 22
362# define R300_GB_TEX4_SOURCE_SHIFT 24
363# define R300_GB_TEX5_SOURCE_SHIFT 26
364# define R300_GB_TEX6_SOURCE_SHIFT 28
365# define R300_GB_TEX7_SOURCE_SHIFT 30
366
367/* MSPOS - positions for multisample antialiasing (?) */
368#define R300_GB_MSPOS0 0x4010
369 /* shifts - each of the fields is 4 bits */
370# define R300_GB_MSPOS0__MS_X0_SHIFT 0
371# define R300_GB_MSPOS0__MS_Y0_SHIFT 4
372# define R300_GB_MSPOS0__MS_X1_SHIFT 8
373# define R300_GB_MSPOS0__MS_Y1_SHIFT 12
374# define R300_GB_MSPOS0__MS_X2_SHIFT 16
375# define R300_GB_MSPOS0__MS_Y2_SHIFT 20
376# define R300_GB_MSPOS0__MSBD0_Y 24
377# define R300_GB_MSPOS0__MSBD0_X 28
378
379#define R300_GB_MSPOS1 0x4014
380# define R300_GB_MSPOS1__MS_X3_SHIFT 0
381# define R300_GB_MSPOS1__MS_Y3_SHIFT 4
382# define R300_GB_MSPOS1__MS_X4_SHIFT 8
383# define R300_GB_MSPOS1__MS_Y4_SHIFT 12
384# define R300_GB_MSPOS1__MS_X5_SHIFT 16
385# define R300_GB_MSPOS1__MS_Y5_SHIFT 20
386# define R300_GB_MSPOS1__MSBD1 24
387
388
389#define R300_GB_TILE_CONFIG 0x4018
390# define R300_GB_TILE_ENABLE (1<<0)
391# define R300_GB_TILE_PIPE_COUNT_RV300 0
392# define R300_GB_TILE_PIPE_COUNT_R300 (3<<1)
393# define R300_GB_TILE_PIPE_COUNT_R420 (7<<1)
394# define R300_GB_TILE_SIZE_8 0
395# define R300_GB_TILE_SIZE_16 (1<<4)
396# define R300_GB_TILE_SIZE_32 (2<<4)
397# define R300_GB_SUPER_SIZE_1 (0<<6)
398# define R300_GB_SUPER_SIZE_2 (1<<6)
399# define R300_GB_SUPER_SIZE_4 (2<<6)
400# define R300_GB_SUPER_SIZE_8 (3<<6)
401# define R300_GB_SUPER_SIZE_16 (4<<6)
402# define R300_GB_SUPER_SIZE_32 (5<<6)
403# define R300_GB_SUPER_SIZE_64 (6<<6)
404# define R300_GB_SUPER_SIZE_128 (7<<6)
405# define R300_GB_SUPER_X_SHIFT 9 /* 3 bits wide */
406# define R300_GB_SUPER_Y_SHIFT 12 /* 3 bits wide */
407# define R300_GB_SUPER_TILE_A 0
408# define R300_GB_SUPER_TILE_B (1<<15)
409# define R300_GB_SUBPIXEL_1_12 0
410# define R300_GB_SUBPIXEL_1_16 (1<<16)
411
412#define R300_GB_FIFO_SIZE 0x4024
413 /* each of the following is 2 bits wide */
414#define R300_GB_FIFO_SIZE_32 0
415#define R300_GB_FIFO_SIZE_64 1
416#define R300_GB_FIFO_SIZE_128 2
417#define R300_GB_FIFO_SIZE_256 3
418# define R300_SC_IFIFO_SIZE_SHIFT 0
419# define R300_SC_TZFIFO_SIZE_SHIFT 2
420# define R300_SC_BFIFO_SIZE_SHIFT 4
421
422# define R300_US_OFIFO_SIZE_SHIFT 12
423# define R300_US_WFIFO_SIZE_SHIFT 14
424 /* the following use the same constants as above, but meaning is
425 is times 2 (i.e. instead of 32 words it means 64 */
426# define R300_RS_TFIFO_SIZE_SHIFT 6
427# define R300_RS_CFIFO_SIZE_SHIFT 8
428# define R300_US_RAM_SIZE_SHIFT 10
429 /* watermarks, 3 bits wide */
430# define R300_RS_HIGHWATER_COL_SHIFT 16
431# define R300_RS_HIGHWATER_TEX_SHIFT 19
432# define R300_OFIFO_HIGHWATER_SHIFT 22 /* two bits only */
433# define R300_CUBE_FIFO_HIGHWATER_COL_SHIFT 24
434
435#define R300_GB_SELECT 0x401C
436# define R300_GB_FOG_SELECT_C0A 0
437# define R300_GB_FOG_SELECT_C1A 1
438# define R300_GB_FOG_SELECT_C2A 2
439# define R300_GB_FOG_SELECT_C3A 3
440# define R300_GB_FOG_SELECT_1_1_W 4
441# define R300_GB_FOG_SELECT_Z 5
442# define R300_GB_DEPTH_SELECT_Z 0
443# define R300_GB_DEPTH_SELECT_1_1_W (1<<3)
444# define R300_GB_W_SELECT_1_W 0
445# define R300_GB_W_SELECT_1 (1<<4)
446
447#define R300_GB_AA_CONFIG 0x4020
448# define R300_AA_ENABLE 0x01
449# define R300_AA_SUBSAMPLES_2 0
450# define R300_AA_SUBSAMPLES_3 (1<<1)
451# define R300_AA_SUBSAMPLES_4 (2<<1)
452# define R300_AA_SUBSAMPLES_6 (3<<1)
453
454/* END */
455
456/* gap */
457/* The upper enable bits are guessed, based on fglrx reported limits. */
458#define R300_TX_ENABLE 0x4104
459# define R300_TX_ENABLE_0 (1 << 0)
460# define R300_TX_ENABLE_1 (1 << 1)
461# define R300_TX_ENABLE_2 (1 << 2)
462# define R300_TX_ENABLE_3 (1 << 3)
463# define R300_TX_ENABLE_4 (1 << 4)
464# define R300_TX_ENABLE_5 (1 << 5)
465# define R300_TX_ENABLE_6 (1 << 6)
466# define R300_TX_ENABLE_7 (1 << 7)
467# define R300_TX_ENABLE_8 (1 << 8)
468# define R300_TX_ENABLE_9 (1 << 9)
469# define R300_TX_ENABLE_10 (1 << 10)
470# define R300_TX_ENABLE_11 (1 << 11)
471# define R300_TX_ENABLE_12 (1 << 12)
472# define R300_TX_ENABLE_13 (1 << 13)
473# define R300_TX_ENABLE_14 (1 << 14)
474# define R300_TX_ENABLE_15 (1 << 15)
475
476/* The pointsize is given in multiples of 6. The pointsize can be
477// enormous: Clear() renders a single point that fills the entire
478// framebuffer. */
479#define R300_RE_POINTSIZE 0x421C
480# define R300_POINTSIZE_Y_SHIFT 0
481# define R300_POINTSIZE_Y_MASK (0xFFFF << 0) /* GUESS */
482# define R300_POINTSIZE_X_SHIFT 16
483# define R300_POINTSIZE_X_MASK (0xFFFF << 16) /* GUESS */
484# define R300_POINTSIZE_MAX (R300_POINTSIZE_Y_MASK / 6)
485
486/* The line width is given in multiples of 6.
487 In default mode lines are classified as vertical lines.
488 HO: horizontal
489 VE: vertical or horizontal
490 HO & VE: no classification
491*/
492#define R300_RE_LINE_CNT 0x4234
493# define R300_LINESIZE_SHIFT 0
494# define R300_LINESIZE_MASK (0xFFFF << 0) /* GUESS */
495# define R300_LINESIZE_MAX (R300_LINESIZE_MASK / 6)
496# define R300_LINE_CNT_HO (1 << 16)
497# define R300_LINE_CNT_VE (1 << 17)
498
499/* Some sort of scale or clamp value for texcoordless textures. */
500#define R300_RE_UNK4238 0x4238
501
502#define R300_RE_SHADE_MODEL 0x4278
503# define R300_RE_SHADE_MODEL_SMOOTH 0x3aaaa
504# define R300_RE_SHADE_MODEL_FLAT 0x39595
505
506/* Dangerous */
507#define R300_RE_POLYGON_MODE 0x4288
508# define R300_PM_ENABLED (1 << 0)
509# define R300_PM_FRONT_POINT (0 << 0)
510# define R300_PM_BACK_POINT (0 << 0)
511# define R300_PM_FRONT_LINE (1 << 4)
512# define R300_PM_FRONT_FILL (1 << 5)
513# define R300_PM_BACK_LINE (1 << 7)
514# define R300_PM_BACK_FILL (1 << 8)
515
516/* Not sure why there are duplicate of factor and constant values.
517 My best guess so far is that there are seperate zbiases for test and write.
518 Ordering might be wrong.
519 Some of the tests indicate that fgl has a fallback implementation of zbias
520 via pixel shaders. */
521#define R300_RE_ZBIAS_T_FACTOR 0x42A4
522#define R300_RE_ZBIAS_T_CONSTANT 0x42A8
523#define R300_RE_ZBIAS_W_FACTOR 0x42AC
524#define R300_RE_ZBIAS_W_CONSTANT 0x42B0
525
526/* This register needs to be set to (1<<1) for RV350 to correctly
527 perform depth test (see --vb-triangles in r300_demo)
528 Don't know about other chips. - Vladimir
529 This is set to 3 when GL_POLYGON_OFFSET_FILL is on.
530 My guess is that there are two bits for each zbias primitive (FILL, LINE, POINT).
531 One to enable depth test and one for depth write.
532 Yet this doesnt explain why depth writes work ...
533 */
534#define R300_RE_OCCLUSION_CNTL 0x42B4
535# define R300_OCCLUSION_ON (1<<1)
536
537#define R300_RE_CULL_CNTL 0x42B8
538# define R300_CULL_FRONT (1 << 0)
539# define R300_CULL_BACK (1 << 1)
540# define R300_FRONT_FACE_CCW (0 << 2)
541# define R300_FRONT_FACE_CW (1 << 2)
542
543
544/* BEGIN: Rasterization / Interpolators - many guesses
545// 0_UNKNOWN_18 has always been set except for clear operations.
546// TC_CNT is the number of incoming texture coordinate sets (i.e. it depends
547// on the vertex program, *not* the fragment program) */
548#define R300_RS_CNTL_0 0x4300
549# define R300_RS_CNTL_TC_CNT_SHIFT 2
550# define R300_RS_CNTL_TC_CNT_MASK (7 << 2)
551# define R300_RS_CNTL_CI_CNT_SHIFT 7 /* number of color interpolators used */
552# define R300_RS_CNTL_0_UNKNOWN_18 (1 << 18)
553/* Guess: RS_CNTL_1 holds the index of the highest used RS_ROUTE_n register. */
554#define R300_RS_CNTL_1 0x4304
555
556/* gap */
557/* Only used for texture coordinates.
558// Use the source field to route texture coordinate input from the vertex program
559// to the desired interpolator. Note that the source field is relative to the
560// outputs the vertex program *actually* writes. If a vertex program only writes
561// texcoord[1], this will be source index 0.
562// Set INTERP_USED on all interpolators that produce data used by the
563// fragment program. INTERP_USED looks like a swizzling mask, but
564// I haven't seen it used that way.
565//
566// Note: The _UNKNOWN constants are always set in their respective register.
567// I don't know if this is necessary. */
568#define R300_RS_INTERP_0 0x4310
569#define R300_RS_INTERP_1 0x4314
570# define R300_RS_INTERP_1_UNKNOWN 0x40
571#define R300_RS_INTERP_2 0x4318
572# define R300_RS_INTERP_2_UNKNOWN 0x80
573#define R300_RS_INTERP_3 0x431C
574# define R300_RS_INTERP_3_UNKNOWN 0xC0
575#define R300_RS_INTERP_4 0x4320
576#define R300_RS_INTERP_5 0x4324
577#define R300_RS_INTERP_6 0x4328
578#define R300_RS_INTERP_7 0x432C
579# define R300_RS_INTERP_SRC_SHIFT 2
580# define R300_RS_INTERP_SRC_MASK (7 << 2)
581# define R300_RS_INTERP_USED 0x00D10000
582
583/* These DWORDs control how vertex data is routed into fragment program
584// registers, after interpolators. */
585#define R300_RS_ROUTE_0 0x4330
586#define R300_RS_ROUTE_1 0x4334
587#define R300_RS_ROUTE_2 0x4338
588#define R300_RS_ROUTE_3 0x433C /* GUESS */
589#define R300_RS_ROUTE_4 0x4340 /* GUESS */
590#define R300_RS_ROUTE_5 0x4344 /* GUESS */
591#define R300_RS_ROUTE_6 0x4348 /* GUESS */
592#define R300_RS_ROUTE_7 0x434C /* GUESS */
593# define R300_RS_ROUTE_SOURCE_INTERP_0 0
594# define R300_RS_ROUTE_SOURCE_INTERP_1 1
595# define R300_RS_ROUTE_SOURCE_INTERP_2 2
596# define R300_RS_ROUTE_SOURCE_INTERP_3 3
597# define R300_RS_ROUTE_SOURCE_INTERP_4 4
598# define R300_RS_ROUTE_SOURCE_INTERP_5 5 /* GUESS */
599# define R300_RS_ROUTE_SOURCE_INTERP_6 6 /* GUESS */
600# define R300_RS_ROUTE_SOURCE_INTERP_7 7 /* GUESS */
601# define R300_RS_ROUTE_ENABLE (1 << 3) /* GUESS */
602# define R300_RS_ROUTE_DEST_SHIFT 6
603# define R300_RS_ROUTE_DEST_MASK (31 << 6) /* GUESS */
604
605/* Special handling for color: When the fragment program uses color,
606// the ROUTE_0_COLOR bit is set and ROUTE_0_COLOR_DEST contains the
607// color register index. */
608# define R300_RS_ROUTE_0_COLOR (1 << 14)
609# define R300_RS_ROUTE_0_COLOR_DEST_SHIFT 17
610# define R300_RS_ROUTE_0_COLOR_DEST_MASK (31 << 17) /* GUESS */
611/* As above, but for secondary color */
612# define R300_RS_ROUTE_1_COLOR1 (1 << 14)
613# define R300_RS_ROUTE_1_COLOR1_DEST_SHIFT 17
614# define R300_RS_ROUTE_1_COLOR1_DEST_MASK (31 << 17)
615# define R300_RS_ROUTE_1_UNKNOWN11 (1 << 11)
616/* END */
617
618/* BEGIN: Scissors and cliprects
619// There are four clipping rectangles. Their corner coordinates are inclusive.
620// Every pixel is assigned a number from 0 and 15 by setting bits 0-3 depending
621// on whether the pixel is inside cliprects 0-3, respectively. For example,
622// if a pixel is inside cliprects 0 and 1, but outside 2 and 3, it is assigned
623// the number 3 (binary 0011).
624// Iff the bit corresponding to the pixel's number in RE_CLIPRECT_CNTL is set,
625// the pixel is rasterized.
626//
627// In addition to this, there is a scissors rectangle. Only pixels inside the
628// scissors rectangle are drawn. (coordinates are inclusive)
629//
630// For some reason, the top-left corner of the framebuffer is at (1440, 1440)
631// for the purpose of clipping and scissors. */
632#define R300_RE_CLIPRECT_TL_0 0x43B0
633#define R300_RE_CLIPRECT_BR_0 0x43B4
634#define R300_RE_CLIPRECT_TL_1 0x43B8
635#define R300_RE_CLIPRECT_BR_1 0x43BC
636#define R300_RE_CLIPRECT_TL_2 0x43C0
637#define R300_RE_CLIPRECT_BR_2 0x43C4
638#define R300_RE_CLIPRECT_TL_3 0x43C8
639#define R300_RE_CLIPRECT_BR_3 0x43CC
640# define R300_CLIPRECT_OFFSET 1440
641# define R300_CLIPRECT_MASK 0x1FFF
642# define R300_CLIPRECT_X_SHIFT 0
643# define R300_CLIPRECT_X_MASK (0x1FFF << 0)
644# define R300_CLIPRECT_Y_SHIFT 13
645# define R300_CLIPRECT_Y_MASK (0x1FFF << 13)
646#define R300_RE_CLIPRECT_CNTL 0x43D0
647# define R300_CLIP_OUT (1 << 0)
648# define R300_CLIP_0 (1 << 1)
649# define R300_CLIP_1 (1 << 2)
650# define R300_CLIP_10 (1 << 3)
651# define R300_CLIP_2 (1 << 4)
652# define R300_CLIP_20 (1 << 5)
653# define R300_CLIP_21 (1 << 6)
654# define R300_CLIP_210 (1 << 7)
655# define R300_CLIP_3 (1 << 8)
656# define R300_CLIP_30 (1 << 9)
657# define R300_CLIP_31 (1 << 10)
658# define R300_CLIP_310 (1 << 11)
659# define R300_CLIP_32 (1 << 12)
660# define R300_CLIP_320 (1 << 13)
661# define R300_CLIP_321 (1 << 14)
662# define R300_CLIP_3210 (1 << 15)
663
664/* gap */
665#define R300_RE_SCISSORS_TL 0x43E0
666#define R300_RE_SCISSORS_BR 0x43E4
667# define R300_SCISSORS_OFFSET 1440
668# define R300_SCISSORS_X_SHIFT 0
669# define R300_SCISSORS_X_MASK (0x1FFF << 0)
670# define R300_SCISSORS_Y_SHIFT 13
671# define R300_SCISSORS_Y_MASK (0x1FFF << 13)
672/* END */
673
674/* BEGIN: Texture specification
675// The texture specification dwords are grouped by meaning and not by texture unit.
676// This means that e.g. the offset for texture image unit N is found in register
677// TX_OFFSET_0 + (4*N) */
678#define R300_TX_FILTER_0 0x4400
679# define R300_TX_REPEAT 0
680# define R300_TX_MIRRORED 1
681# define R300_TX_CLAMP 4
682# define R300_TX_CLAMP_TO_EDGE 2
683# define R300_TX_CLAMP_TO_BORDER 6
684# define R300_TX_WRAP_S_SHIFT 0
685# define R300_TX_WRAP_S_MASK (7 << 0)
686# define R300_TX_WRAP_T_SHIFT 3
687# define R300_TX_WRAP_T_MASK (7 << 3)
688# define R300_TX_WRAP_Q_SHIFT 6
689# define R300_TX_WRAP_Q_MASK (7 << 6)
690# define R300_TX_MAG_FILTER_NEAREST (1 << 9)
691# define R300_TX_MAG_FILTER_LINEAR (2 << 9)
692# define R300_TX_MAG_FILTER_MASK (3 << 9)
693# define R300_TX_MIN_FILTER_NEAREST (1 << 11)
694# define R300_TX_MIN_FILTER_LINEAR (2 << 11)
695# define R300_TX_MIN_FILTER_NEAREST_MIP_NEAREST (5 << 11)
696# define R300_TX_MIN_FILTER_NEAREST_MIP_LINEAR (9 << 11)
697# define R300_TX_MIN_FILTER_LINEAR_MIP_NEAREST (6 << 11)
698# define R300_TX_MIN_FILTER_LINEAR_MIP_LINEAR (10 << 11)
699
700/* NOTE: NEAREST doesnt seem to exist.
701 Im not seting MAG_FILTER_MASK and (3 << 11) on for all
702 anisotropy modes because that would void selected mag filter */
703# define R300_TX_MIN_FILTER_ANISO_NEAREST ((0 << 13) /*|R300_TX_MAG_FILTER_MASK|(3<<11)*/)
704# define R300_TX_MIN_FILTER_ANISO_LINEAR ((0 << 13) /*|R300_TX_MAG_FILTER_MASK|(3<<11)*/)
705# define R300_TX_MIN_FILTER_ANISO_NEAREST_MIP_NEAREST ((1 << 13) /*|R300_TX_MAG_FILTER_MASK|(3<<11)*/)
706# define R300_TX_MIN_FILTER_ANISO_NEAREST_MIP_LINEAR ((2 << 13) /*|R300_TX_MAG_FILTER_MASK|(3<<11)*/)
707# define R300_TX_MIN_FILTER_MASK ( (15 << 11) | (3 << 13) )
708# define R300_TX_MAX_ANISO_1_TO_1 (0 << 21)
709# define R300_TX_MAX_ANISO_2_TO_1 (2 << 21)
710# define R300_TX_MAX_ANISO_4_TO_1 (4 << 21)
711# define R300_TX_MAX_ANISO_8_TO_1 (6 << 21)
712# define R300_TX_MAX_ANISO_16_TO_1 (8 << 21)
713# define R300_TX_MAX_ANISO_MASK (14 << 21)
714
715#define R300_TX_UNK1_0 0x4440
716# define R300_LOD_BIAS_MASK 0x1fff
717
718#define R300_TX_SIZE_0 0x4480
719# define R300_TX_WIDTHMASK_SHIFT 0
720# define R300_TX_WIDTHMASK_MASK (2047 << 0)
721# define R300_TX_HEIGHTMASK_SHIFT 11
722# define R300_TX_HEIGHTMASK_MASK (2047 << 11)
723# define R300_TX_UNK23 (1 << 23)
724# define R300_TX_SIZE_SHIFT 26 /* largest of width, height */
725# define R300_TX_SIZE_MASK (15 << 26)
726#define R300_TX_FORMAT_0 0x44C0
727 /* The interpretation of the format word by Wladimir van der Laan */
728 /* The X, Y, Z and W refer to the layout of the components.
729 They are given meanings as R, G, B and Alpha by the swizzle
730 specification */
731# define R300_TX_FORMAT_X8 0x0
732# define R300_TX_FORMAT_X16 0x1
733# define R300_TX_FORMAT_Y4X4 0x2
734# define R300_TX_FORMAT_Y8X8 0x3
735# define R300_TX_FORMAT_Y16X16 0x4
736# define R300_TX_FORMAT_Z3Y3X2 0x5
737# define R300_TX_FORMAT_Z5Y6X5 0x6
738# define R300_TX_FORMAT_Z6Y5X5 0x7
739# define R300_TX_FORMAT_Z11Y11X10 0x8
740# define R300_TX_FORMAT_Z10Y11X11 0x9
741# define R300_TX_FORMAT_W4Z4Y4X4 0xA
742# define R300_TX_FORMAT_W1Z5Y5X5 0xB
743# define R300_TX_FORMAT_W8Z8Y8X8 0xC
744# define R300_TX_FORMAT_W2Z10Y10X10 0xD
745# define R300_TX_FORMAT_W16Z16Y16X16 0xE
746# define R300_TX_FORMAT_DXT1 0xF
747# define R300_TX_FORMAT_DXT3 0x10
748# define R300_TX_FORMAT_DXT5 0x11
749# define R300_TX_FORMAT_D3DMFT_CxV8U8 0x12 /* no swizzle */
750# define R300_TX_FORMAT_A8R8G8B8 0x13 /* no swizzle */
751# define R300_TX_FORMAT_B8G8_B8G8 0x14 /* no swizzle */
752# define R300_TX_FORMAT_G8R8_G8B8 0x15 /* no swizzle */
753 /* 0x16 - some 16 bit green format.. ?? */
754# define R300_TX_FORMAT_UNK25 (1 << 25) /* no swizzle */
755
756 /* gap */
757 /* Floating point formats */
758 /* Note - hardware supports both 16 and 32 bit floating point */
759# define R300_TX_FORMAT_FL_I16 0x18
760# define R300_TX_FORMAT_FL_I16A16 0x19
761# define R300_TX_FORMAT_FL_R16G16B16A16 0x1A
762# define R300_TX_FORMAT_FL_I32 0x1B
763# define R300_TX_FORMAT_FL_I32A32 0x1C
764# define R300_TX_FORMAT_FL_R32G32B32A32 0x1D
765 /* alpha modes, convenience mostly */
766 /* if you have alpha, pick constant appropriate to the
767 number of channels (1 for I8, 2 for I8A8, 4 for R8G8B8A8, etc */
768# define R300_TX_FORMAT_ALPHA_1CH 0x000
769# define R300_TX_FORMAT_ALPHA_2CH 0x200
770# define R300_TX_FORMAT_ALPHA_4CH 0x600
771# define R300_TX_FORMAT_ALPHA_NONE 0xA00
772 /* Swizzling */
773 /* constants */
774# define R300_TX_FORMAT_X 0
775# define R300_TX_FORMAT_Y 1
776# define R300_TX_FORMAT_Z 2
777# define R300_TX_FORMAT_W 3
778# define R300_TX_FORMAT_ZERO 4
779# define R300_TX_FORMAT_ONE 5
780# define R300_TX_FORMAT_CUT_Z 6 /* 2.0*Z, everything above 1.0 is set to 0.0 */
781# define R300_TX_FORMAT_CUT_W 7 /* 2.0*W, everything above 1.0 is set to 0.0 */
782
783# define R300_TX_FORMAT_B_SHIFT 18
784# define R300_TX_FORMAT_G_SHIFT 15
785# define R300_TX_FORMAT_R_SHIFT 12
786# define R300_TX_FORMAT_A_SHIFT 9
787 /* Convenience macro to take care of layout and swizzling */
788# define R300_EASY_TX_FORMAT(B, G, R, A, FMT) (\
789 ((R300_TX_FORMAT_##B)<<R300_TX_FORMAT_B_SHIFT) \
790 | ((R300_TX_FORMAT_##G)<<R300_TX_FORMAT_G_SHIFT) \
791 | ((R300_TX_FORMAT_##R)<<R300_TX_FORMAT_R_SHIFT) \
792 | ((R300_TX_FORMAT_##A)<<R300_TX_FORMAT_A_SHIFT) \
793 | (R300_TX_FORMAT_##FMT) \
794 )
795 /* These can be ORed with result of R300_EASY_TX_FORMAT() */
796 /* We don't really know what they do. Take values from a constant color ? */
797# define R300_TX_FORMAT_CONST_X (1<<5)
798# define R300_TX_FORMAT_CONST_Y (2<<5)
799# define R300_TX_FORMAT_CONST_Z (4<<5)
800# define R300_TX_FORMAT_CONST_W (8<<5)
801
802# define R300_TX_FORMAT_YUV_MODE 0x00800000
803
804#define R300_TX_OFFSET_0 0x4540
805/* BEGIN: Guess from R200 */
806# define R300_TXO_ENDIAN_NO_SWAP (0 << 0)
807# define R300_TXO_ENDIAN_BYTE_SWAP (1 << 0)
808# define R300_TXO_ENDIAN_WORD_SWAP (2 << 0)
809# define R300_TXO_ENDIAN_HALFDW_SWAP (3 << 0)
810# define R300_TXO_OFFSET_MASK 0xffffffe0
811# define R300_TXO_OFFSET_SHIFT 5
812/* END */
813#define R300_TX_UNK4_0 0x4580
814#define R300_TX_BORDER_COLOR_0 0x45C0 //ff00ff00 == { 0, 1.0, 0, 1.0 }
815
816/* END */
817
818/* BEGIN: Fragment program instruction set
819// Fragment programs are written directly into register space.
820// There are separate instruction streams for texture instructions and ALU
821// instructions.
822// In order to synchronize these streams, the program is divided into up
823// to 4 nodes. Each node begins with a number of TEX operations, followed
824// by a number of ALU operations.
825// The first node can have zero TEX ops, all subsequent nodes must have at least
826// one TEX ops.
827// All nodes must have at least one ALU op.
828//
829// The index of the last node is stored in PFS_CNTL_0: A value of 0 means
830// 1 node, a value of 3 means 4 nodes.
831// The total amount of instructions is defined in PFS_CNTL_2. The offsets are
832// offsets into the respective instruction streams, while *_END points to the
833// last instruction relative to this offset. */
834#define R300_PFS_CNTL_0 0x4600
835# define R300_PFS_CNTL_LAST_NODES_SHIFT 0
836# define R300_PFS_CNTL_LAST_NODES_MASK (3 << 0)
837# define R300_PFS_CNTL_FIRST_NODE_HAS_TEX (1 << 3)
838#define R300_PFS_CNTL_1 0x4604
839/* There is an unshifted value here which has so far always been equal to the
840// index of the highest used temporary register. */
841#define R300_PFS_CNTL_2 0x4608
842# define R300_PFS_CNTL_ALU_OFFSET_SHIFT 0
843# define R300_PFS_CNTL_ALU_OFFSET_MASK (63 << 0)
844# define R300_PFS_CNTL_ALU_END_SHIFT 6
845# define R300_PFS_CNTL_ALU_END_MASK (63 << 0)
846# define R300_PFS_CNTL_TEX_OFFSET_SHIFT 12
847# define R300_PFS_CNTL_TEX_OFFSET_MASK (31 << 12) /* GUESS */
848# define R300_PFS_CNTL_TEX_END_SHIFT 18
849# define R300_PFS_CNTL_TEX_END_MASK (31 << 18) /* GUESS */
850
851/* gap */
852/* Nodes are stored backwards. The last active node is always stored in
853// PFS_NODE_3.
854// Example: In a 2-node program, NODE_0 and NODE_1 are set to 0. The
855// first node is stored in NODE_2, the second node is stored in NODE_3.
856//
857// Offsets are relative to the master offset from PFS_CNTL_2.
858// LAST_NODE is set for the last node, and only for the last node. */
859#define R300_PFS_NODE_0 0x4610
860#define R300_PFS_NODE_1 0x4614
861#define R300_PFS_NODE_2 0x4618
862#define R300_PFS_NODE_3 0x461C
863# define R300_PFS_NODE_ALU_OFFSET_SHIFT 0
864# define R300_PFS_NODE_ALU_OFFSET_MASK (63 << 0)
865# define R300_PFS_NODE_ALU_END_SHIFT 6
866# define R300_PFS_NODE_ALU_END_MASK (63 << 6)
867# define R300_PFS_NODE_TEX_OFFSET_SHIFT 12
868# define R300_PFS_NODE_TEX_OFFSET_MASK (31 << 12)
869# define R300_PFS_NODE_TEX_END_SHIFT 17
870# define R300_PFS_NODE_TEX_END_MASK (31 << 17)
871# define R300_PFS_NODE_LAST_NODE (1 << 22)
872
873/* TEX
874// As far as I can tell, texture instructions cannot write into output
875// registers directly. A subsequent ALU instruction is always necessary,
876// even if it's just MAD o0, r0, 1, 0 */
877#define R300_PFS_TEXI_0 0x4620
878# define R300_FPITX_SRC_SHIFT 0
879# define R300_FPITX_SRC_MASK (31 << 0)
880# define R300_FPITX_SRC_CONST (1 << 5) /* GUESS */
881# define R300_FPITX_DST_SHIFT 6
882# define R300_FPITX_DST_MASK (31 << 6)
883# define R300_FPITX_IMAGE_SHIFT 11
884# define R300_FPITX_IMAGE_MASK (15 << 11) /* GUESS based on layout and native limits */
885/* Unsure if these are opcodes, or some kind of bitfield, but this is how
886 * they were set when I checked
887 */
888# define R300_FPITX_OPCODE_SHIFT 15
889# define R300_FPITX_OP_TEX 1
890# define R300_FPITX_OP_TXP 3
891# define R300_FPITX_OP_TXB 4
892
893/* ALU
894// The ALU instructions register blocks are enumerated according to the order
895// in which fglrx. I assume there is space for 64 instructions, since
896// each block has space for a maximum of 64 DWORDs, and this matches reported
897// native limits.
898//
899// The basic functional block seems to be one MAD for each color and alpha,
900// and an adder that adds all components after the MUL.
901// - ADD, MUL, MAD etc.: use MAD with appropriate neutral operands
902// - DP4: Use OUTC_DP4, OUTA_DP4
903// - DP3: Use OUTC_DP3, OUTA_DP4, appropriate alpha operands
904// - DPH: Use OUTC_DP4, OUTA_DP4, appropriate alpha operands
905// - CMP: If ARG2 < 0, return ARG1, else return ARG0
906// - FLR: use FRC+MAD
907// - XPD: use MAD+MAD
908// - SGE, SLT: use MAD+CMP
909// - RSQ: use ABS modifier for argument
910// - Use OUTC_REPL_ALPHA to write results of an alpha-only operation (e.g. RCP)
911// into color register
912// - apparently, there's no quick DST operation
913// - fglrx set FPI2_UNKNOWN_31 on a "MAD fragment.color, tmp0, tmp1, tmp2"
914// - fglrx set FPI2_UNKNOWN_31 on a "MAX r2, r1, c0"
915// - fglrx once set FPI0_UNKNOWN_31 on a "FRC r1, r1"
916//
917// Operand selection
918// First stage selects three sources from the available registers and
919// constant parameters. This is defined in INSTR1 (color) and INSTR3 (alpha).
920// fglrx sorts the three source fields: Registers before constants,
921// lower indices before higher indices; I do not know whether this is necessary.
922// fglrx fills unused sources with "read constant 0"
923// According to specs, you cannot select more than two different constants.
924//
925// Second stage selects the operands from the sources. This is defined in
926// INSTR0 (color) and INSTR2 (alpha). You can also select the special constants
927// zero and one.
928// Swizzling and negation happens in this stage, as well.
929//
930// Important: Color and alpha seem to be mostly separate, i.e. their sources
931// selection appears to be fully independent (the register storage is probably
932// physically split into a color and an alpha section).
933// However (because of the apparent physical split), there is some interaction
934// WRT swizzling. If, for example, you want to load an R component into an
935// Alpha operand, this R component is taken from a *color* source, not from
936// an alpha source. The corresponding register doesn't even have to appear in
937// the alpha sources list. (I hope this alll makes sense to you)
938//
939// Destination selection
940// The destination register index is in FPI1 (color) and FPI3 (alpha) together
941// with enable bits.
942// There are separate enable bits for writing into temporary registers
943// (DSTC_REG_* /DSTA_REG) and and program output registers (DSTC_OUTPUT_* /DSTA_OUTPUT).
944// You can write to both at once, or not write at all (the same index
945// must be used for both).
946//
947// Note: There is a special form for LRP
948// - Argument order is the same as in ARB_fragment_program.
949// - Operation is MAD
950// - ARG1 is set to ARGC_SRC1C_LRP/ARGC_SRC1A_LRP
951// - Set FPI0/FPI2_SPECIAL_LRP
952// Arbitrary LRP (including support for swizzling) requires vanilla MAD+MAD */
953#define R300_PFS_INSTR1_0 0x46C0
954# define R300_FPI1_SRC0C_SHIFT 0
955# define R300_FPI1_SRC0C_MASK (31 << 0)
956# define R300_FPI1_SRC0C_CONST (1 << 5)
957# define R300_FPI1_SRC1C_SHIFT 6
958# define R300_FPI1_SRC1C_MASK (31 << 6)
959# define R300_FPI1_SRC1C_CONST (1 << 11)
960# define R300_FPI1_SRC2C_SHIFT 12
961# define R300_FPI1_SRC2C_MASK (31 << 12)
962# define R300_FPI1_SRC2C_CONST (1 << 17)
963# define R300_FPI1_DSTC_SHIFT 18
964# define R300_FPI1_DSTC_MASK (31 << 18)
965# define R300_FPI1_DSTC_REG_X (1 << 23)
966# define R300_FPI1_DSTC_REG_Y (1 << 24)
967# define R300_FPI1_DSTC_REG_Z (1 << 25)
968# define R300_FPI1_DSTC_OUTPUT_X (1 << 26)
969# define R300_FPI1_DSTC_OUTPUT_Y (1 << 27)
970# define R300_FPI1_DSTC_OUTPUT_Z (1 << 28)
971
972#define R300_PFS_INSTR3_0 0x47C0
973# define R300_FPI3_SRC0A_SHIFT 0
974# define R300_FPI3_SRC0A_MASK (31 << 0)
975# define R300_FPI3_SRC0A_CONST (1 << 5)
976# define R300_FPI3_SRC1A_SHIFT 6
977# define R300_FPI3_SRC1A_MASK (31 << 6)
978# define R300_FPI3_SRC1A_CONST (1 << 11)
979# define R300_FPI3_SRC2A_SHIFT 12
980# define R300_FPI3_SRC2A_MASK (31 << 12)
981# define R300_FPI3_SRC2A_CONST (1 << 17)
982# define R300_FPI3_DSTA_SHIFT 18
983# define R300_FPI3_DSTA_MASK (31 << 18)
984# define R300_FPI3_DSTA_REG (1 << 23)
985# define R300_FPI3_DSTA_OUTPUT (1 << 24)
986
987#define R300_PFS_INSTR0_0 0x48C0
988# define R300_FPI0_ARGC_SRC0C_XYZ 0
989# define R300_FPI0_ARGC_SRC0C_XXX 1
990# define R300_FPI0_ARGC_SRC0C_YYY 2
991# define R300_FPI0_ARGC_SRC0C_ZZZ 3
992# define R300_FPI0_ARGC_SRC1C_XYZ 4
993# define R300_FPI0_ARGC_SRC1C_XXX 5
994# define R300_FPI0_ARGC_SRC1C_YYY 6
995# define R300_FPI0_ARGC_SRC1C_ZZZ 7
996# define R300_FPI0_ARGC_SRC2C_XYZ 8
997# define R300_FPI0_ARGC_SRC2C_XXX 9
998# define R300_FPI0_ARGC_SRC2C_YYY 10
999# define R300_FPI0_ARGC_SRC2C_ZZZ 11
1000# define R300_FPI0_ARGC_SRC0A 12
1001# define R300_FPI0_ARGC_SRC1A 13
1002# define R300_FPI0_ARGC_SRC2A 14
1003# define R300_FPI0_ARGC_SRC1C_LRP 15
1004# define R300_FPI0_ARGC_ZERO 20
1005# define R300_FPI0_ARGC_ONE 21
1006# define R300_FPI0_ARGC_HALF 22 /* GUESS */
1007# define R300_FPI0_ARGC_SRC0C_YZX 23
1008# define R300_FPI0_ARGC_SRC1C_YZX 24
1009# define R300_FPI0_ARGC_SRC2C_YZX 25
1010# define R300_FPI0_ARGC_SRC0C_ZXY 26
1011# define R300_FPI0_ARGC_SRC1C_ZXY 27
1012# define R300_FPI0_ARGC_SRC2C_ZXY 28
1013# define R300_FPI0_ARGC_SRC0CA_WZY 29
1014# define R300_FPI0_ARGC_SRC1CA_WZY 30
1015# define R300_FPI0_ARGC_SRC2CA_WZY 31
1016
1017# define R300_FPI0_ARG0C_SHIFT 0
1018# define R300_FPI0_ARG0C_MASK (31 << 0)
1019# define R300_FPI0_ARG0C_NEG (1 << 5)
1020# define R300_FPI0_ARG0C_ABS (1 << 6)
1021# define R300_FPI0_ARG1C_SHIFT 7
1022# define R300_FPI0_ARG1C_MASK (31 << 7)
1023# define R300_FPI0_ARG1C_NEG (1 << 12)
1024# define R300_FPI0_ARG1C_ABS (1 << 13)
1025# define R300_FPI0_ARG2C_SHIFT 14
1026# define R300_FPI0_ARG2C_MASK (31 << 14)
1027# define R300_FPI0_ARG2C_NEG (1 << 19)
1028# define R300_FPI0_ARG2C_ABS (1 << 20)
1029# define R300_FPI0_SPECIAL_LRP (1 << 21)
1030# define R300_FPI0_OUTC_MAD (0 << 23)
1031# define R300_FPI0_OUTC_DP3 (1 << 23)
1032# define R300_FPI0_OUTC_DP4 (2 << 23)
1033# define R300_FPI0_OUTC_MIN (4 << 23)
1034# define R300_FPI0_OUTC_MAX (5 << 23)
1035# define R300_FPI0_OUTC_CMP (8 << 23)
1036# define R300_FPI0_OUTC_FRC (9 << 23)
1037# define R300_FPI0_OUTC_REPL_ALPHA (10 << 23)
1038# define R300_FPI0_OUTC_SAT (1 << 30)
1039# define R300_FPI0_UNKNOWN_31 (1 << 31)
1040
1041#define R300_PFS_INSTR2_0 0x49C0
1042# define R300_FPI2_ARGA_SRC0C_X 0
1043# define R300_FPI2_ARGA_SRC0C_Y 1
1044# define R300_FPI2_ARGA_SRC0C_Z 2
1045# define R300_FPI2_ARGA_SRC1C_X 3
1046# define R300_FPI2_ARGA_SRC1C_Y 4
1047# define R300_FPI2_ARGA_SRC1C_Z 5
1048# define R300_FPI2_ARGA_SRC2C_X 6
1049# define R300_FPI2_ARGA_SRC2C_Y 7
1050# define R300_FPI2_ARGA_SRC2C_Z 8
1051# define R300_FPI2_ARGA_SRC0A 9
1052# define R300_FPI2_ARGA_SRC1A 10
1053# define R300_FPI2_ARGA_SRC2A 11
1054# define R300_FPI2_ARGA_SRC1A_LRP 15
1055# define R300_FPI2_ARGA_ZERO 16
1056# define R300_FPI2_ARGA_ONE 17
1057# define R300_FPI2_ARGA_HALF 18 /* GUESS */
1058
1059# define R300_FPI2_ARG0A_SHIFT 0
1060# define R300_FPI2_ARG0A_MASK (31 << 0)
1061# define R300_FPI2_ARG0A_NEG (1 << 5)
1062# define R300_FPI2_ARG0A_ABS (1 << 6) /* GUESS */
1063# define R300_FPI2_ARG1A_SHIFT 7
1064# define R300_FPI2_ARG1A_MASK (31 << 7)
1065# define R300_FPI2_ARG1A_NEG (1 << 12)
1066# define R300_FPI2_ARG1A_ABS (1 << 13) /* GUESS */
1067# define R300_FPI2_ARG2A_SHIFT 14
1068# define R300_FPI2_ARG2A_MASK (31 << 14)
1069# define R300_FPI2_ARG2A_NEG (1 << 19)
1070# define R300_FPI2_ARG2A_ABS (1 << 20) /* GUESS */
1071# define R300_FPI2_SPECIAL_LRP (1 << 21)
1072# define R300_FPI2_OUTA_MAD (0 << 23)
1073# define R300_FPI2_OUTA_DP4 (1 << 23)
1074# define R300_FPI2_OUTA_MIN (2 << 23)
1075# define R300_FPI2_OUTA_MAX (3 << 23)
1076# define R300_FPI2_OUTA_CMP (6 << 23)
1077# define R300_FPI2_OUTA_FRC (7 << 23)
1078# define R300_FPI2_OUTA_EX2 (8 << 23)
1079# define R300_FPI2_OUTA_LG2 (9 << 23)
1080# define R300_FPI2_OUTA_RCP (10 << 23)
1081# define R300_FPI2_OUTA_RSQ (11 << 23)
1082# define R300_FPI2_OUTA_SAT (1 << 30)
1083# define R300_FPI2_UNKNOWN_31 (1 << 31)
1084/* END */
1085
1086/* gap */
1087#define R300_PP_ALPHA_TEST 0x4BD4
1088# define R300_REF_ALPHA_MASK 0x000000ff
1089# define R300_ALPHA_TEST_FAIL (0 << 8)
1090# define R300_ALPHA_TEST_LESS (1 << 8)
1091# define R300_ALPHA_TEST_LEQUAL (3 << 8)
1092# define R300_ALPHA_TEST_EQUAL (2 << 8)
1093# define R300_ALPHA_TEST_GEQUAL (6 << 8)
1094# define R300_ALPHA_TEST_GREATER (4 << 8)
1095# define R300_ALPHA_TEST_NEQUAL (5 << 8)
1096# define R300_ALPHA_TEST_PASS (7 << 8)
1097# define R300_ALPHA_TEST_OP_MASK (7 << 8)
1098# define R300_ALPHA_TEST_ENABLE (1 << 11)
1099
1100/* gap */
1101/* Fragment program parameters in 7.16 floating point */
1102#define R300_PFS_PARAM_0_X 0x4C00
1103#define R300_PFS_PARAM_0_Y 0x4C04
1104#define R300_PFS_PARAM_0_Z 0x4C08
1105#define R300_PFS_PARAM_0_W 0x4C0C
1106/* GUESS: PARAM_31 is last, based on native limits reported by fglrx */
1107#define R300_PFS_PARAM_31_X 0x4DF0
1108#define R300_PFS_PARAM_31_Y 0x4DF4
1109#define R300_PFS_PARAM_31_Z 0x4DF8
1110#define R300_PFS_PARAM_31_W 0x4DFC
1111
1112/* Notes:
1113// - AFAIK fglrx always sets BLEND_UNKNOWN when blending is used in the application
1114// - AFAIK fglrx always sets BLEND_NO_SEPARATE when CBLEND and ABLEND are set to the same
1115// function (both registers are always set up completely in any case)
1116// - Most blend flags are simply copied from R200 and not tested yet */
1117#define R300_RB3D_CBLEND 0x4E04
1118#define R300_RB3D_ABLEND 0x4E08
1119 /* the following only appear in CBLEND */
1120# define R300_BLEND_ENABLE (1 << 0)
1121# define R300_BLEND_UNKNOWN (3 << 1)
1122# define R300_BLEND_NO_SEPARATE (1 << 3)
1123 /* the following are shared between CBLEND and ABLEND */
1124# define R300_FCN_MASK (3 << 12)
1125# define R300_COMB_FCN_ADD_CLAMP (0 << 12)
1126# define R300_COMB_FCN_ADD_NOCLAMP (1 << 12)
1127# define R300_COMB_FCN_SUB_CLAMP (2 << 12)
1128# define R300_COMB_FCN_SUB_NOCLAMP (3 << 12)
1129# define R300_SRC_BLEND_GL_ZERO (32 << 16)
1130# define R300_SRC_BLEND_GL_ONE (33 << 16)
1131# define R300_SRC_BLEND_GL_SRC_COLOR (34 << 16)
1132# define R300_SRC_BLEND_GL_ONE_MINUS_SRC_COLOR (35 << 16)
1133# define R300_SRC_BLEND_GL_DST_COLOR (36 << 16)
1134# define R300_SRC_BLEND_GL_ONE_MINUS_DST_COLOR (37 << 16)
1135# define R300_SRC_BLEND_GL_SRC_ALPHA (38 << 16)
1136# define R300_SRC_BLEND_GL_ONE_MINUS_SRC_ALPHA (39 << 16)
1137# define R300_SRC_BLEND_GL_DST_ALPHA (40 << 16)
1138# define R300_SRC_BLEND_GL_ONE_MINUS_DST_ALPHA (41 << 16)
1139# define R300_SRC_BLEND_GL_SRC_ALPHA_SATURATE (42 << 16)
1140# define R300_SRC_BLEND_MASK (63 << 16)
1141# define R300_DST_BLEND_GL_ZERO (32 << 24)
1142# define R300_DST_BLEND_GL_ONE (33 << 24)
1143# define R300_DST_BLEND_GL_SRC_COLOR (34 << 24)
1144# define R300_DST_BLEND_GL_ONE_MINUS_SRC_COLOR (35 << 24)
1145# define R300_DST_BLEND_GL_DST_COLOR (36 << 24)
1146# define R300_DST_BLEND_GL_ONE_MINUS_DST_COLOR (37 << 24)
1147# define R300_DST_BLEND_GL_SRC_ALPHA (38 << 24)
1148# define R300_DST_BLEND_GL_ONE_MINUS_SRC_ALPHA (39 << 24)
1149# define R300_DST_BLEND_GL_DST_ALPHA (40 << 24)
1150# define R300_DST_BLEND_GL_ONE_MINUS_DST_ALPHA (41 << 24)
1151# define R300_DST_BLEND_MASK (63 << 24)
1152#define R300_RB3D_COLORMASK 0x4E0C
1153# define R300_COLORMASK0_B (1<<0)
1154# define R300_COLORMASK0_G (1<<1)
1155# define R300_COLORMASK0_R (1<<2)
1156# define R300_COLORMASK0_A (1<<3)
1157
1158/* gap */
1159#define R300_RB3D_COLOROFFSET0 0x4E28
1160# define R300_COLOROFFSET_MASK 0xFFFFFFF0 /* GUESS */
1161#define R300_RB3D_COLOROFFSET1 0x4E2C /* GUESS */
1162#define R300_RB3D_COLOROFFSET2 0x4E30 /* GUESS */
1163#define R300_RB3D_COLOROFFSET3 0x4E34 /* GUESS */
1164/* gap */
1165/* Bit 16: Larger tiles
1166// Bit 17: 4x2 tiles
1167// Bit 18: Extremely weird tile like, but some pixels duplicated? */
1168#define R300_RB3D_COLORPITCH0 0x4E38
1169# define R300_COLORPITCH_MASK 0x00001FF8 /* GUESS */
1170# define R300_COLOR_TILE_ENABLE (1 << 16) /* GUESS */
1171# define R300_COLOR_MICROTILE_ENABLE (1 << 17) /* GUESS */
1172# define R300_COLOR_ENDIAN_NO_SWAP (0 << 18) /* GUESS */
1173# define R300_COLOR_ENDIAN_WORD_SWAP (1 << 18) /* GUESS */
1174# define R300_COLOR_ENDIAN_DWORD_SWAP (2 << 18) /* GUESS */
1175# define R300_COLOR_FORMAT_RGB565 (2 << 22)
1176# define R300_COLOR_FORMAT_ARGB8888 (3 << 22)
1177#define R300_RB3D_COLORPITCH1 0x4E3C /* GUESS */
1178#define R300_RB3D_COLORPITCH2 0x4E40 /* GUESS */
1179#define R300_RB3D_COLORPITCH3 0x4E44 /* GUESS */
1180
1181/* gap */
1182/* Guess by Vladimir.
1183// Set to 0A before 3D operations, set to 02 afterwards. */
1184#define R300_RB3D_DSTCACHE_CTLSTAT 0x4E4C
1185# define R300_RB3D_DSTCACHE_02 0x00000002
1186# define R300_RB3D_DSTCACHE_0A 0x0000000A
1187
1188/* gap */
1189/* There seems to be no "write only" setting, so use Z-test = ALWAYS for this. */
1190/* Bit (1<<8) is the "test" bit. so plain write is 6 - vd */
1191#define R300_RB3D_ZSTENCIL_CNTL_0 0x4F00
1192# define R300_RB3D_Z_DISABLED_1 0x00000010 /* GUESS */
1193# define R300_RB3D_Z_DISABLED_2 0x00000014 /* GUESS */
1194# define R300_RB3D_Z_TEST 0x00000012
1195# define R300_RB3D_Z_TEST_AND_WRITE 0x00000016
1196# define R300_RB3D_Z_WRITE_ONLY 0x00000006
1197
1198# define R300_RB3D_Z_TEST 0x00000012
1199# define R300_RB3D_Z_TEST_AND_WRITE 0x00000016
1200# define R300_RB3D_Z_WRITE_ONLY 0x00000006
1201# define R300_RB3D_STENCIL_ENABLE 0x00000001
1202
1203#define R300_RB3D_ZSTENCIL_CNTL_1 0x4F04
1204 /* functions */
1205# define R300_ZS_NEVER 0
1206# define R300_ZS_LESS 1
1207# define R300_ZS_LEQUAL 2
1208# define R300_ZS_EQUAL 3
1209# define R300_ZS_GEQUAL 4
1210# define R300_ZS_GREATER 5
1211# define R300_ZS_NOTEQUAL 6
1212# define R300_ZS_ALWAYS 7
1213# define R300_ZS_MASK 7
1214 /* operations */
1215# define R300_ZS_KEEP 0
1216# define R300_ZS_ZERO 1
1217# define R300_ZS_REPLACE 2
1218# define R300_ZS_INCR 3
1219# define R300_ZS_DECR 4
1220# define R300_ZS_INVERT 5
1221# define R300_ZS_INCR_WRAP 6
1222# define R300_ZS_DECR_WRAP 7
1223
1224 /* front and back refer to operations done for front
1225 and back faces, i.e. separate stencil function support */
1226# define R300_RB3D_ZS1_DEPTH_FUNC_SHIFT 0
1227# define R300_RB3D_ZS1_FRONT_FUNC_SHIFT 3
1228# define R300_RB3D_ZS1_FRONT_FAIL_OP_SHIFT 6
1229# define R300_RB3D_ZS1_FRONT_ZPASS_OP_SHIFT 9
1230# define R300_RB3D_ZS1_FRONT_ZFAIL_OP_SHIFT 12
1231# define R300_RB3D_ZS1_BACK_FUNC_SHIFT 15
1232# define R300_RB3D_ZS1_BACK_FAIL_OP_SHIFT 18
1233# define R300_RB3D_ZS1_BACK_ZPASS_OP_SHIFT 21
1234# define R300_RB3D_ZS1_BACK_ZFAIL_OP_SHIFT 24
1235
1236
1237
1238#define R300_RB3D_ZSTENCIL_CNTL_2 0x4F08
1239# define R300_RB3D_ZS2_STENCIL_REF_SHIFT 0
1240# define R300_RB3D_ZS2_STENCIL_MASK 0xFF
1241# define R300_RB3D_ZS2_STENCIL_MASK_SHIFT 8
1242# define R300_RB3D_ZS2_STENCIL_WRITE_MASK_SHIFT 16
1243
1244/* gap */
1245
1246#define R300_RB3D_ZSTENCIL_FORMAT 0x4F10
1247# define R300_DEPTH_FORMAT_16BIT_INT_Z (0 << 0)
1248# define R300_DEPTH_FORMAT_24BIT_INT_Z (2 << 0)
1249
1250/* gap */
1251#define R300_RB3D_DEPTHOFFSET 0x4F20
1252#define R300_RB3D_DEPTHPITCH 0x4F24
1253# define R300_DEPTHPITCH_MASK 0x00001FF8 /* GUESS */
1254# define R300_DEPTH_TILE_ENABLE (1 << 16) /* GUESS */
1255# define R300_DEPTH_MICROTILE_ENABLE (1 << 17) /* GUESS */
1256# define R300_DEPTH_ENDIAN_NO_SWAP (0 << 18) /* GUESS */
1257# define R300_DEPTH_ENDIAN_WORD_SWAP (1 << 18) /* GUESS */
1258# define R300_DEPTH_ENDIAN_DWORD_SWAP (2 << 18) /* GUESS */
1259
1260/* BEGIN: Vertex program instruction set
1261// Every instruction is four dwords long:
1262// DWORD 0: output and opcode
1263// DWORD 1: first argument
1264// DWORD 2: second argument
1265// DWORD 3: third argument
1266//
1267// Notes:
1268// - ABS r, a is implemented as MAX r, a, -a
1269// - MOV is implemented as ADD to zero
1270// - XPD is implemented as MUL + MAD
1271// - FLR is implemented as FRC + ADD
1272// - apparently, fglrx tries to schedule instructions so that there is at least
1273// one instruction between the write to a temporary and the first read
1274// from said temporary; however, violations of this scheduling are allowed
1275// - register indices seem to be unrelated with OpenGL aliasing to conventional state
1276// - only one attribute and one parameter can be loaded at a time; however, the
1277// same attribute/parameter can be used for more than one argument
1278// - the second software argument for POW is the third hardware argument (no idea why)
1279// - MAD with only temporaries as input seems to use VPI_OUT_SELECT_MAD_2
1280//
1281// There is some magic surrounding LIT:
1282// The single argument is replicated across all three inputs, but swizzled:
1283// First argument: xyzy
1284// Second argument: xyzx
1285// Third argument: xyzw
1286// Whenever the result is used later in the fragment program, fglrx forces x and w
1287// to be 1.0 in the input selection; I don't know whether this is strictly necessary */
1288#define R300_VPI_OUT_OP_DOT (1 << 0)
1289#define R300_VPI_OUT_OP_MUL (2 << 0)
1290#define R300_VPI_OUT_OP_ADD (3 << 0)
1291#define R300_VPI_OUT_OP_MAD (4 << 0)
1292#define R300_VPI_OUT_OP_DST (5 << 0)
1293#define R300_VPI_OUT_OP_FRC (6 << 0)
1294#define R300_VPI_OUT_OP_MAX (7 << 0)
1295#define R300_VPI_OUT_OP_MIN (8 << 0)
1296#define R300_VPI_OUT_OP_SGE (9 << 0)
1297#define R300_VPI_OUT_OP_SLT (10 << 0)
1298#define R300_VPI_OUT_OP_UNK12 (12 << 0) /* Used in GL_POINT_DISTANCE_ATTENUATION_ARB, vector(scalar, vector) */
1299#define R300_VPI_OUT_OP_EXP (65 << 0)
1300#define R300_VPI_OUT_OP_LOG (66 << 0)
1301#define R300_VPI_OUT_OP_UNK67 (67 << 0) /* Used in fog computations, scalar(scalar) */
1302#define R300_VPI_OUT_OP_LIT (68 << 0)
1303#define R300_VPI_OUT_OP_POW (69 << 0)
1304#define R300_VPI_OUT_OP_RCP (70 << 0)
1305#define R300_VPI_OUT_OP_RSQ (72 << 0)
1306#define R300_VPI_OUT_OP_UNK73 (73 << 0) /* Used in GL_POINT_DISTANCE_ATTENUATION_ARB, scalar(scalar) */
1307#define R300_VPI_OUT_OP_EX2 (75 << 0)
1308#define R300_VPI_OUT_OP_LG2 (76 << 0)
1309#define R300_VPI_OUT_OP_MAD_2 (128 << 0)
1310#define R300_VPI_OUT_OP_UNK129 (129 << 0) /* all temps, vector(scalar, vector, vector) */
1311
1312#define R300_VPI_OUT_REG_CLASS_TEMPORARY (0 << 8)
1313#define R300_VPI_OUT_REG_CLASS_RESULT (2 << 8)
1314#define R300_VPI_OUT_REG_CLASS_MASK (31 << 8)
1315
1316#define R300_VPI_OUT_REG_INDEX_SHIFT 13
1317#define R300_VPI_OUT_REG_INDEX_MASK (31 << 13) /* GUESS based on fglrx native limits */
1318
1319#define R300_VPI_OUT_WRITE_X (1 << 20)
1320#define R300_VPI_OUT_WRITE_Y (1 << 21)
1321#define R300_VPI_OUT_WRITE_Z (1 << 22)
1322#define R300_VPI_OUT_WRITE_W (1 << 23)
1323
1324#define R300_VPI_IN_REG_CLASS_TEMPORARY (0 << 0)
1325#define R300_VPI_IN_REG_CLASS_ATTRIBUTE (1 << 0)
1326#define R300_VPI_IN_REG_CLASS_PARAMETER (2 << 0)
1327#define R300_VPI_IN_REG_CLASS_NONE (9 << 0)
1328#define R300_VPI_IN_REG_CLASS_MASK (31 << 0) /* GUESS */
1329
1330#define R300_VPI_IN_REG_INDEX_SHIFT 5
1331#define R300_VPI_IN_REG_INDEX_MASK (255 << 5) /* GUESS based on fglrx native limits */
1332
1333/* The R300 can select components from the input register arbitrarily.
1334// Use the following constants, shifted by the component shift you
1335// want to select */
1336#define R300_VPI_IN_SELECT_X 0
1337#define R300_VPI_IN_SELECT_Y 1
1338#define R300_VPI_IN_SELECT_Z 2
1339#define R300_VPI_IN_SELECT_W 3
1340#define R300_VPI_IN_SELECT_ZERO 4
1341#define R300_VPI_IN_SELECT_ONE 5
1342#define R300_VPI_IN_SELECT_MASK 7
1343
1344#define R300_VPI_IN_X_SHIFT 13
1345#define R300_VPI_IN_Y_SHIFT 16
1346#define R300_VPI_IN_Z_SHIFT 19
1347#define R300_VPI_IN_W_SHIFT 22
1348
1349#define R300_VPI_IN_NEG_X (1 << 25)
1350#define R300_VPI_IN_NEG_Y (1 << 26)
1351#define R300_VPI_IN_NEG_Z (1 << 27)
1352#define R300_VPI_IN_NEG_W (1 << 28)
1353/* END */
1354
1355//BEGIN: Packet 3 commands
1356
1357// A primitive emission dword.
1358#define R300_PRIM_TYPE_NONE (0 << 0)
1359#define R300_PRIM_TYPE_POINT (1 << 0)
1360#define R300_PRIM_TYPE_LINE (2 << 0)
1361#define R300_PRIM_TYPE_LINE_STRIP (3 << 0)
1362#define R300_PRIM_TYPE_TRI_LIST (4 << 0)
1363#define R300_PRIM_TYPE_TRI_FAN (5 << 0)
1364#define R300_PRIM_TYPE_TRI_STRIP (6 << 0)
1365#define R300_PRIM_TYPE_TRI_TYPE2 (7 << 0)
1366#define R300_PRIM_TYPE_RECT_LIST (8 << 0)
1367#define R300_PRIM_TYPE_3VRT_POINT_LIST (9 << 0)
1368#define R300_PRIM_TYPE_3VRT_LINE_LIST (10 << 0)
1369#define R300_PRIM_TYPE_POINT_SPRITES (11 << 0) // GUESS (based on r200)
1370#define R300_PRIM_TYPE_LINE_LOOP (12 << 0)
1371#define R300_PRIM_TYPE_QUADS (13 << 0)
1372#define R300_PRIM_TYPE_QUAD_STRIP (14 << 0)
1373#define R300_PRIM_TYPE_POLYGON (15 << 0)
1374#define R300_PRIM_TYPE_MASK 0xF
1375#define R300_PRIM_WALK_IND (1 << 4)
1376#define R300_PRIM_WALK_LIST (2 << 4)
1377#define R300_PRIM_WALK_RING (3 << 4)
1378#define R300_PRIM_WALK_MASK (3 << 4)
1379#define R300_PRIM_COLOR_ORDER_BGRA (0 << 6) // GUESS (based on r200)
1380#define R300_PRIM_COLOR_ORDER_RGBA (1 << 6) // GUESS
1381#define R300_PRIM_NUM_VERTICES_SHIFT 16
1382
1383// Draw a primitive from vertex data in arrays loaded via 3D_LOAD_VBPNTR.
1384// Two parameter dwords:
1385// 0. The first parameter appears to be always 0
1386// 1. The second parameter is a standard primitive emission dword.
1387#define R300_PACKET3_3D_DRAW_VBUF 0x00002800
1388
1389// Specify the full set of vertex arrays as (address, stride).
1390// The first parameter is the number of vertex arrays specified.
1391// The rest of the command is a variable length list of blocks, where
1392// each block is three dwords long and specifies two arrays.
1393// The first dword of a block is split into two words, the lower significant
1394// word refers to the first array, the more significant word to the second
1395// array in the block.
1396// The low byte of each word contains the size of an array entry in dwords,
1397// the high byte contains the stride of the array.
1398// The second dword of a block contains the pointer to the first array,
1399// the third dword of a block contains the pointer to the second array.
1400// Note that if the total number of arrays is odd, the third dword of
1401// the last block is omitted.
1402#define R300_PACKET3_3D_LOAD_VBPNTR 0x00002F00
1403
1404#define R300_PACKET3_INDX_BUFFER 0x00003300
1405# define R300_EB_UNK1_SHIFT 24
1406# define R300_EB_UNK1 (0x80<<24)
1407# define R300_EB_UNK2 0x0810
1408#define R300_PACKET3_3D_DRAW_INDX_2 0x00003600
1409
1410//END
1411
1412#endif /* _R300_REG_H */
diff --git a/drivers/char/drm/radeon_cp.c b/drivers/char/drm/radeon_cp.c
index 20bcf872b348..6d9080a3ca7e 100644
--- a/drivers/char/drm/radeon_cp.c
+++ b/drivers/char/drm/radeon_cp.c
@@ -32,6 +32,7 @@
32#include "drm.h" 32#include "drm.h"
33#include "radeon_drm.h" 33#include "radeon_drm.h"
34#include "radeon_drv.h" 34#include "radeon_drv.h"
35#include "r300_reg.h"
35 36
36#define RADEON_FIFO_DEBUG 0 37#define RADEON_FIFO_DEBUG 0
37 38
@@ -1151,6 +1152,8 @@ static void radeon_cp_init_ring_buffer( drm_device_t *dev,
1151 1152
1152#if __OS_HAS_AGP 1153#if __OS_HAS_AGP
1153 if ( !dev_priv->is_pci ) { 1154 if ( !dev_priv->is_pci ) {
1155 /* set RADEON_AGP_BASE here instead of relying on X from user space */
1156 RADEON_WRITE(RADEON_AGP_BASE, (unsigned int)dev->agp->base);
1154 RADEON_WRITE( RADEON_CP_RB_RPTR_ADDR, 1157 RADEON_WRITE( RADEON_CP_RB_RPTR_ADDR,
1155 dev_priv->ring_rptr->offset 1158 dev_priv->ring_rptr->offset
1156 - dev->agp->base 1159 - dev->agp->base
@@ -1407,6 +1410,7 @@ static int radeon_do_init_cp( drm_device_t *dev, drm_radeon_init_t *init )
1407 radeon_do_cleanup_cp(dev); 1410 radeon_do_cleanup_cp(dev);
1408 return DRM_ERR(EINVAL); 1411 return DRM_ERR(EINVAL);
1409 } 1412 }
1413 dev->agp_buffer_token = init->buffers_offset;
1410 dev->agp_buffer_map = drm_core_findmap(dev, init->buffers_offset); 1414 dev->agp_buffer_map = drm_core_findmap(dev, init->buffers_offset);
1411 if(!dev->agp_buffer_map) { 1415 if(!dev->agp_buffer_map) {
1412 DRM_ERROR("could not find dma buffer region!\n"); 1416 DRM_ERROR("could not find dma buffer region!\n");
@@ -1625,6 +1629,9 @@ int radeon_cp_init( DRM_IOCTL_ARGS )
1625 1629
1626 DRM_COPY_FROM_USER_IOCTL( init, (drm_radeon_init_t __user *)data, sizeof(init) ); 1630 DRM_COPY_FROM_USER_IOCTL( init, (drm_radeon_init_t __user *)data, sizeof(init) );
1627 1631
1632 if(init.func == RADEON_INIT_R300_CP)
1633 r300_init_reg_flags();
1634
1628 switch ( init.func ) { 1635 switch ( init.func ) {
1629 case RADEON_INIT_CP: 1636 case RADEON_INIT_CP:
1630 case RADEON_INIT_R200_CP: 1637 case RADEON_INIT_R200_CP:
@@ -2039,15 +2046,43 @@ int radeon_driver_preinit(struct drm_device *dev, unsigned long flags)
2039 case CHIP_RV200: 2046 case CHIP_RV200:
2040 case CHIP_R200: 2047 case CHIP_R200:
2041 case CHIP_R300: 2048 case CHIP_R300:
2049 case CHIP_R420:
2042 dev_priv->flags |= CHIP_HAS_HIERZ; 2050 dev_priv->flags |= CHIP_HAS_HIERZ;
2043 break; 2051 break;
2044 default: 2052 default:
2045 /* all other chips have no hierarchical z buffer */ 2053 /* all other chips have no hierarchical z buffer */
2046 break; 2054 break;
2047 } 2055 }
2056
2057 if (drm_device_is_agp(dev))
2058 dev_priv->flags |= CHIP_IS_AGP;
2059
2060 DRM_DEBUG("%s card detected\n",
2061 ((dev_priv->flags & CHIP_IS_AGP) ? "AGP" : "PCI"));
2048 return ret; 2062 return ret;
2049} 2063}
2050 2064
2065int radeon_presetup(struct drm_device *dev)
2066{
2067 int ret;
2068 drm_local_map_t *map;
2069 drm_radeon_private_t *dev_priv = dev->dev_private;
2070
2071 ret = drm_addmap(dev, drm_get_resource_start(dev, 2),
2072 drm_get_resource_len(dev, 2), _DRM_REGISTERS,
2073 _DRM_READ_ONLY, &dev_priv->mmio);
2074 if (ret != 0)
2075 return ret;
2076
2077 ret = drm_addmap(dev, drm_get_resource_start(dev, 0),
2078 drm_get_resource_len(dev, 0), _DRM_FRAME_BUFFER,
2079 _DRM_WRITE_COMBINING, &map);
2080 if (ret != 0)
2081 return ret;
2082
2083 return 0;
2084}
2085
2051int radeon_driver_postcleanup(struct drm_device *dev) 2086int radeon_driver_postcleanup(struct drm_device *dev)
2052{ 2087{
2053 drm_radeon_private_t *dev_priv = dev->dev_private; 2088 drm_radeon_private_t *dev_priv = dev->dev_private;
diff --git a/drivers/char/drm/radeon_drm.h b/drivers/char/drm/radeon_drm.h
index c1e62d047989..3792798270a4 100644
--- a/drivers/char/drm/radeon_drm.h
+++ b/drivers/char/drm/radeon_drm.h
@@ -195,6 +195,52 @@ typedef union {
195#define RADEON_WAIT_2D 0x1 195#define RADEON_WAIT_2D 0x1
196#define RADEON_WAIT_3D 0x2 196#define RADEON_WAIT_3D 0x2
197 197
198/* Allowed parameters for R300_CMD_PACKET3
199 */
200#define R300_CMD_PACKET3_CLEAR 0
201#define R300_CMD_PACKET3_RAW 1
202
203/* Commands understood by cmd_buffer ioctl for R300.
204 * The interface has not been stabilized, so some of these may be removed
205 * and eventually reordered before stabilization.
206 */
207#define R300_CMD_PACKET0 1
208#define R300_CMD_VPU 2 /* emit vertex program upload */
209#define R300_CMD_PACKET3 3 /* emit a packet3 */
210#define R300_CMD_END3D 4 /* emit sequence ending 3d rendering */
211#define R300_CMD_CP_DELAY 5
212#define R300_CMD_DMA_DISCARD 6
213#define R300_CMD_WAIT 7
214# define R300_WAIT_2D 0x1
215# define R300_WAIT_3D 0x2
216# define R300_WAIT_2D_CLEAN 0x3
217# define R300_WAIT_3D_CLEAN 0x4
218
219typedef union {
220 unsigned int u;
221 struct {
222 unsigned char cmd_type, pad0, pad1, pad2;
223 } header;
224 struct {
225 unsigned char cmd_type, count, reglo, reghi;
226 } packet0;
227 struct {
228 unsigned char cmd_type, count, adrlo, adrhi;
229 } vpu;
230 struct {
231 unsigned char cmd_type, packet, pad0, pad1;
232 } packet3;
233 struct {
234 unsigned char cmd_type, packet;
235 unsigned short count; /* amount of packet2 to emit */
236 } delay;
237 struct {
238 unsigned char cmd_type, buf_idx, pad0, pad1;
239 } dma;
240 struct {
241 unsigned char cmd_type, flags, pad0, pad1;
242 } wait;
243} drm_r300_cmd_header_t;
198 244
199#define RADEON_FRONT 0x1 245#define RADEON_FRONT 0x1
200#define RADEON_BACK 0x2 246#define RADEON_BACK 0x2
diff --git a/drivers/char/drm/radeon_drv.c b/drivers/char/drm/radeon_drv.c
index 18e4e5b0952f..e0682f64b400 100644
--- a/drivers/char/drm/radeon_drv.c
+++ b/drivers/char/drm/radeon_drv.c
@@ -76,6 +76,7 @@ static struct drm_driver driver = {
76 .driver_features = DRIVER_USE_AGP | DRIVER_USE_MTRR | DRIVER_PCI_DMA | DRIVER_SG | DRIVER_HAVE_IRQ | DRIVER_HAVE_DMA | DRIVER_IRQ_SHARED | DRIVER_IRQ_VBL, 76 .driver_features = DRIVER_USE_AGP | DRIVER_USE_MTRR | DRIVER_PCI_DMA | DRIVER_SG | DRIVER_HAVE_IRQ | DRIVER_HAVE_DMA | DRIVER_IRQ_SHARED | DRIVER_IRQ_VBL,
77 .dev_priv_size = sizeof(drm_radeon_buf_priv_t), 77 .dev_priv_size = sizeof(drm_radeon_buf_priv_t),
78 .preinit = radeon_driver_preinit, 78 .preinit = radeon_driver_preinit,
79 .presetup = radeon_presetup,
79 .postcleanup = radeon_driver_postcleanup, 80 .postcleanup = radeon_driver_postcleanup,
80 .prerelease = radeon_driver_prerelease, 81 .prerelease = radeon_driver_prerelease,
81 .pretakedown = radeon_driver_pretakedown, 82 .pretakedown = radeon_driver_pretakedown,
diff --git a/drivers/char/drm/radeon_drv.h b/drivers/char/drm/radeon_drv.h
index 771aa80a5e8c..f12a963ede18 100644
--- a/drivers/char/drm/radeon_drv.h
+++ b/drivers/char/drm/radeon_drv.h
@@ -82,9 +82,10 @@
82 * - Add support for r100 cube maps 82 * - Add support for r100 cube maps
83 * 1.16- Add R200_EMIT_PP_TRI_PERF_CNTL packet to support brilinear 83 * 1.16- Add R200_EMIT_PP_TRI_PERF_CNTL packet to support brilinear
84 * texture filtering on r200 84 * texture filtering on r200
85 * 1.17- Add initial support for R300 (3D).
85 */ 86 */
86#define DRIVER_MAJOR 1 87#define DRIVER_MAJOR 1
87#define DRIVER_MINOR 16 88#define DRIVER_MINOR 17
88#define DRIVER_PATCHLEVEL 0 89#define DRIVER_PATCHLEVEL 0
89 90
90#define GET_RING_HEAD(dev_priv) DRM_READ32( (dev_priv)->ring_rptr, 0 ) 91#define GET_RING_HEAD(dev_priv) DRM_READ32( (dev_priv)->ring_rptr, 0 )
@@ -106,7 +107,9 @@ enum radeon_family {
106 CHIP_RV280, 107 CHIP_RV280,
107 CHIP_R300, 108 CHIP_R300,
108 CHIP_RS300, 109 CHIP_RS300,
110 CHIP_R350,
109 CHIP_RV350, 111 CHIP_RV350,
112 CHIP_R420,
110 CHIP_LAST, 113 CHIP_LAST,
111}; 114};
112 115
@@ -290,6 +293,7 @@ extern int radeon_wait_ring( drm_radeon_private_t *dev_priv, int n );
290extern int radeon_do_cp_idle( drm_radeon_private_t *dev_priv ); 293extern int radeon_do_cp_idle( drm_radeon_private_t *dev_priv );
291 294
292extern int radeon_driver_preinit(struct drm_device *dev, unsigned long flags); 295extern int radeon_driver_preinit(struct drm_device *dev, unsigned long flags);
296extern int radeon_presetup(struct drm_device *dev);
293extern int radeon_driver_postcleanup(struct drm_device *dev); 297extern int radeon_driver_postcleanup(struct drm_device *dev);
294 298
295extern int radeon_mem_alloc( DRM_IOCTL_ARGS ); 299extern int radeon_mem_alloc( DRM_IOCTL_ARGS );
@@ -320,6 +324,14 @@ extern int radeon_postcleanup( struct drm_device *dev );
320extern long radeon_compat_ioctl(struct file *filp, unsigned int cmd, 324extern long radeon_compat_ioctl(struct file *filp, unsigned int cmd,
321 unsigned long arg); 325 unsigned long arg);
322 326
327
328/* r300_cmdbuf.c */
329extern void r300_init_reg_flags(void);
330
331extern int r300_do_cp_cmdbuf(drm_device_t* dev, DRMFILE filp,
332 drm_file_t* filp_priv,
333 drm_radeon_cmd_buffer_t* cmdbuf);
334
323/* Flags for stats.boxes 335/* Flags for stats.boxes
324 */ 336 */
325#define RADEON_BOX_DMA_IDLE 0x1 337#define RADEON_BOX_DMA_IDLE 0x1
@@ -357,6 +369,11 @@ extern long radeon_compat_ioctl(struct file *filp, unsigned int cmd,
357#define RADEON_CRTC2_OFFSET 0x0324 369#define RADEON_CRTC2_OFFSET 0x0324
358#define RADEON_CRTC2_OFFSET_CNTL 0x0328 370#define RADEON_CRTC2_OFFSET_CNTL 0x0328
359 371
372#define RADEON_MPP_TB_CONFIG 0x01c0
373#define RADEON_MEM_CNTL 0x0140
374#define RADEON_MEM_SDRAM_MODE_REG 0x0158
375#define RADEON_AGP_BASE 0x0170
376
360#define RADEON_RB3D_COLOROFFSET 0x1c40 377#define RADEON_RB3D_COLOROFFSET 0x1c40
361#define RADEON_RB3D_COLORPITCH 0x1c48 378#define RADEON_RB3D_COLORPITCH 0x1c48
362 379
@@ -651,16 +668,27 @@ extern long radeon_compat_ioctl(struct file *filp, unsigned int cmd,
651#define RADEON_CP_PACKET1 0x40000000 668#define RADEON_CP_PACKET1 0x40000000
652#define RADEON_CP_PACKET2 0x80000000 669#define RADEON_CP_PACKET2 0x80000000
653#define RADEON_CP_PACKET3 0xC0000000 670#define RADEON_CP_PACKET3 0xC0000000
671# define RADEON_CP_NOP 0x00001000
672# define RADEON_CP_NEXT_CHAR 0x00001900
673# define RADEON_CP_PLY_NEXTSCAN 0x00001D00
674# define RADEON_CP_SET_SCISSORS 0x00001E00
675 /* GEN_INDX_PRIM is unsupported starting with R300 */
654# define RADEON_3D_RNDR_GEN_INDX_PRIM 0x00002300 676# define RADEON_3D_RNDR_GEN_INDX_PRIM 0x00002300
655# define RADEON_WAIT_FOR_IDLE 0x00002600 677# define RADEON_WAIT_FOR_IDLE 0x00002600
656# define RADEON_3D_DRAW_VBUF 0x00002800 678# define RADEON_3D_DRAW_VBUF 0x00002800
657# define RADEON_3D_DRAW_IMMD 0x00002900 679# define RADEON_3D_DRAW_IMMD 0x00002900
658# define RADEON_3D_DRAW_INDX 0x00002A00 680# define RADEON_3D_DRAW_INDX 0x00002A00
681# define RADEON_CP_LOAD_PALETTE 0x00002C00
659# define RADEON_3D_LOAD_VBPNTR 0x00002F00 682# define RADEON_3D_LOAD_VBPNTR 0x00002F00
660# define RADEON_MPEG_IDCT_MACROBLOCK 0x00003000 683# define RADEON_MPEG_IDCT_MACROBLOCK 0x00003000
661# define RADEON_MPEG_IDCT_MACROBLOCK_REV 0x00003100 684# define RADEON_MPEG_IDCT_MACROBLOCK_REV 0x00003100
662# define RADEON_3D_CLEAR_ZMASK 0x00003200 685# define RADEON_3D_CLEAR_ZMASK 0x00003200
686# define RADEON_CP_INDX_BUFFER 0x00003300
687# define RADEON_CP_3D_DRAW_VBUF_2 0x00003400
688# define RADEON_CP_3D_DRAW_IMMD_2 0x00003500
689# define RADEON_CP_3D_DRAW_INDX_2 0x00003600
663# define RADEON_3D_CLEAR_HIZ 0x00003700 690# define RADEON_3D_CLEAR_HIZ 0x00003700
691# define RADEON_CP_3D_CLEAR_CMASK 0x00003802
664# define RADEON_CNTL_HOSTDATA_BLT 0x00009400 692# define RADEON_CNTL_HOSTDATA_BLT 0x00009400
665# define RADEON_CNTL_PAINT_MULTI 0x00009A00 693# define RADEON_CNTL_PAINT_MULTI 0x00009A00
666# define RADEON_CNTL_BITBLT_MULTI 0x00009B00 694# define RADEON_CNTL_BITBLT_MULTI 0x00009B00
diff --git a/drivers/char/drm/radeon_state.c b/drivers/char/drm/radeon_state.c
index 1f79e249146c..64a3e3a406ef 100644
--- a/drivers/char/drm/radeon_state.c
+++ b/drivers/char/drm/radeon_state.c
@@ -1493,7 +1493,7 @@ static void radeon_cp_dispatch_indices( drm_device_t *dev,
1493 1493
1494} 1494}
1495 1495
1496#define RADEON_MAX_TEXTURE_SIZE (RADEON_BUFFER_SIZE - 8 * sizeof(u32)) 1496#define RADEON_MAX_TEXTURE_SIZE RADEON_BUFFER_SIZE
1497 1497
1498static int radeon_cp_dispatch_texture( DRMFILE filp, 1498static int radeon_cp_dispatch_texture( DRMFILE filp,
1499 drm_device_t *dev, 1499 drm_device_t *dev,
@@ -1506,10 +1506,11 @@ static int radeon_cp_dispatch_texture( DRMFILE filp,
1506 u32 format; 1506 u32 format;
1507 u32 *buffer; 1507 u32 *buffer;
1508 const u8 __user *data; 1508 const u8 __user *data;
1509 int size, dwords, tex_width, blit_width; 1509 int size, dwords, tex_width, blit_width, spitch;
1510 u32 height; 1510 u32 height;
1511 int i; 1511 int i;
1512 u32 texpitch, microtile; 1512 u32 texpitch, microtile;
1513 u32 offset;
1513 RING_LOCALS; 1514 RING_LOCALS;
1514 1515
1515 DRM_GET_PRIV_WITH_RETURN( filp_priv, filp ); 1516 DRM_GET_PRIV_WITH_RETURN( filp_priv, filp );
@@ -1530,17 +1531,6 @@ static int radeon_cp_dispatch_texture( DRMFILE filp,
1530 RADEON_WAIT_UNTIL_IDLE(); 1531 RADEON_WAIT_UNTIL_IDLE();
1531 ADVANCE_RING(); 1532 ADVANCE_RING();
1532 1533
1533#ifdef __BIG_ENDIAN
1534 /* The Mesa texture functions provide the data in little endian as the
1535 * chip wants it, but we need to compensate for the fact that the CP
1536 * ring gets byte-swapped
1537 */
1538 BEGIN_RING( 2 );
1539 OUT_RING_REG( RADEON_RBBM_GUICNTL, RADEON_HOST_DATA_SWAP_32BIT );
1540 ADVANCE_RING();
1541#endif
1542
1543
1544 /* The compiler won't optimize away a division by a variable, 1534 /* The compiler won't optimize away a division by a variable,
1545 * even if the only legal values are powers of two. Thus, we'll 1535 * even if the only legal values are powers of two. Thus, we'll
1546 * use a shift instead. 1536 * use a shift instead.
@@ -1572,6 +1562,10 @@ static int radeon_cp_dispatch_texture( DRMFILE filp,
1572 DRM_ERROR( "invalid texture format %d\n", tex->format ); 1562 DRM_ERROR( "invalid texture format %d\n", tex->format );
1573 return DRM_ERR(EINVAL); 1563 return DRM_ERR(EINVAL);
1574 } 1564 }
1565 spitch = blit_width >> 6;
1566 if (spitch == 0 && image->height > 1)
1567 return DRM_ERR(EINVAL);
1568
1575 texpitch = tex->pitch; 1569 texpitch = tex->pitch;
1576 if ((texpitch << 22) & RADEON_DST_TILE_MICRO) { 1570 if ((texpitch << 22) & RADEON_DST_TILE_MICRO) {
1577 microtile = 1; 1571 microtile = 1;
@@ -1624,25 +1618,6 @@ static int radeon_cp_dispatch_texture( DRMFILE filp,
1624 */ 1618 */
1625 buffer = (u32*)((char*)dev->agp_buffer_map->handle + buf->offset); 1619 buffer = (u32*)((char*)dev->agp_buffer_map->handle + buf->offset);
1626 dwords = size / 4; 1620 dwords = size / 4;
1627 buffer[0] = CP_PACKET3( RADEON_CNTL_HOSTDATA_BLT, dwords + 6 );
1628 buffer[1] = (RADEON_GMC_DST_PITCH_OFFSET_CNTL |
1629 RADEON_GMC_BRUSH_NONE |
1630 (format << 8) |
1631 RADEON_GMC_SRC_DATATYPE_COLOR |
1632 RADEON_ROP3_S |
1633 RADEON_DP_SRC_SOURCE_HOST_DATA |
1634 RADEON_GMC_CLR_CMP_CNTL_DIS |
1635 RADEON_GMC_WR_MSK_DIS);
1636
1637 buffer[2] = (texpitch << 22) | (tex->offset >> 10);
1638 buffer[3] = 0xffffffff;
1639 buffer[4] = 0xffffffff;
1640 buffer[5] = (image->y << 16) | image->x;
1641 buffer[6] = (height << 16) | image->width;
1642 buffer[7] = dwords;
1643 buffer += 8;
1644
1645
1646 1621
1647 if (microtile) { 1622 if (microtile) {
1648 /* texture micro tiling in use, minimum texture width is thus 16 bytes. 1623 /* texture micro tiling in use, minimum texture width is thus 16 bytes.
@@ -1750,9 +1725,28 @@ static int radeon_cp_dispatch_texture( DRMFILE filp,
1750 } 1725 }
1751 1726
1752 buf->filp = filp; 1727 buf->filp = filp;
1753 buf->used = (dwords + 8) * sizeof(u32); 1728 buf->used = size;
1754 radeon_cp_dispatch_indirect( dev, buf, 0, buf->used ); 1729 offset = dev_priv->gart_buffers_offset + buf->offset;
1755 radeon_cp_discard_buffer( dev, buf ); 1730 BEGIN_RING(9);
1731 OUT_RING(CP_PACKET3(RADEON_CNTL_BITBLT_MULTI, 5));
1732 OUT_RING(RADEON_GMC_SRC_PITCH_OFFSET_CNTL |
1733 RADEON_GMC_DST_PITCH_OFFSET_CNTL |
1734 RADEON_GMC_BRUSH_NONE |
1735 (format << 8) |
1736 RADEON_GMC_SRC_DATATYPE_COLOR |
1737 RADEON_ROP3_S |
1738 RADEON_DP_SRC_SOURCE_MEMORY |
1739 RADEON_GMC_CLR_CMP_CNTL_DIS |
1740 RADEON_GMC_WR_MSK_DIS );
1741 OUT_RING((spitch << 22) | (offset >> 10));
1742 OUT_RING((texpitch << 22) | (tex->offset >> 10));
1743 OUT_RING(0);
1744 OUT_RING((image->x << 16) | image->y);
1745 OUT_RING((image->width << 16) | height);
1746 RADEON_WAIT_UNTIL_2D_IDLE();
1747 ADVANCE_RING();
1748
1749 radeon_cp_discard_buffer(dev, buf);
1756 1750
1757 /* Update the input parameters for next time */ 1751 /* Update the input parameters for next time */
1758 image->y += height; 1752 image->y += height;
@@ -2797,6 +2791,17 @@ static int radeon_cp_cmdbuf( DRM_IOCTL_ARGS )
2797 2791
2798 orig_nbox = cmdbuf.nbox; 2792 orig_nbox = cmdbuf.nbox;
2799 2793
2794 if(dev_priv->microcode_version == UCODE_R300) {
2795 int temp;
2796 temp=r300_do_cp_cmdbuf(dev, filp, filp_priv, &cmdbuf);
2797
2798 if (orig_bufsz != 0)
2799 drm_free(kbuf, orig_bufsz, DRM_MEM_DRIVER);
2800
2801 return temp;
2802 }
2803
2804 /* microcode_version != r300 */
2800 while ( cmdbuf.bufsz >= sizeof(header) ) { 2805 while ( cmdbuf.bufsz >= sizeof(header) ) {
2801 2806
2802 header.i = *(int *)cmdbuf.buf; 2807 header.i = *(int *)cmdbuf.buf;
diff --git a/drivers/char/drm/savage_bci.c b/drivers/char/drm/savage_bci.c
new file mode 100644
index 000000000000..2fd40bac7c97
--- /dev/null
+++ b/drivers/char/drm/savage_bci.c
@@ -0,0 +1,1096 @@
1/* savage_bci.c -- BCI support for Savage
2 *
3 * Copyright 2004 Felix Kuehling
4 * All Rights Reserved.
5 *
6 * Permission is hereby granted, free of charge, to any person obtaining a
7 * copy of this software and associated documentation files (the "Software"),
8 * to deal in the Software without restriction, including without limitation
9 * the rights to use, copy, modify, merge, publish, distribute, sub license,
10 * and/or sell copies of the Software, and to permit persons to whom the
11 * Software is furnished to do so, subject to the following conditions:
12 *
13 * The above copyright notice and this permission notice (including the
14 * next paragraph) shall be included in all copies or substantial portions
15 * of the Software.
16 *
17 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
18 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
19 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
20 * NON-INFRINGEMENT. IN NO EVENT SHALL FELIX KUEHLING BE LIABLE FOR
21 * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF
22 * CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
23 * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
24 */
25#include "drmP.h"
26#include "savage_drm.h"
27#include "savage_drv.h"
28
29/* Need a long timeout for shadow status updates can take a while
30 * and so can waiting for events when the queue is full. */
31#define SAVAGE_DEFAULT_USEC_TIMEOUT 1000000 /* 1s */
32#define SAVAGE_EVENT_USEC_TIMEOUT 5000000 /* 5s */
33#define SAVAGE_FREELIST_DEBUG 0
34
35static int
36savage_bci_wait_fifo_shadow(drm_savage_private_t *dev_priv, unsigned int n)
37{
38 uint32_t mask = dev_priv->status_used_mask;
39 uint32_t threshold = dev_priv->bci_threshold_hi;
40 uint32_t status;
41 int i;
42
43#if SAVAGE_BCI_DEBUG
44 if (n > dev_priv->cob_size + SAVAGE_BCI_FIFO_SIZE - threshold)
45 DRM_ERROR("Trying to emit %d words "
46 "(more than guaranteed space in COB)\n", n);
47#endif
48
49 for (i = 0; i < SAVAGE_DEFAULT_USEC_TIMEOUT; i++) {
50 DRM_MEMORYBARRIER();
51 status = dev_priv->status_ptr[0];
52 if ((status & mask) < threshold)
53 return 0;
54 DRM_UDELAY(1);
55 }
56
57#if SAVAGE_BCI_DEBUG
58 DRM_ERROR("failed!\n");
59 DRM_INFO(" status=0x%08x, threshold=0x%08x\n", status, threshold);
60#endif
61 return DRM_ERR(EBUSY);
62}
63
64static int
65savage_bci_wait_fifo_s3d(drm_savage_private_t *dev_priv, unsigned int n)
66{
67 uint32_t maxUsed = dev_priv->cob_size + SAVAGE_BCI_FIFO_SIZE - n;
68 uint32_t status;
69 int i;
70
71 for (i = 0; i < SAVAGE_DEFAULT_USEC_TIMEOUT; i++) {
72 status = SAVAGE_READ(SAVAGE_STATUS_WORD0);
73 if ((status & SAVAGE_FIFO_USED_MASK_S3D) <= maxUsed)
74 return 0;
75 DRM_UDELAY(1);
76 }
77
78#if SAVAGE_BCI_DEBUG
79 DRM_ERROR("failed!\n");
80 DRM_INFO(" status=0x%08x\n", status);
81#endif
82 return DRM_ERR(EBUSY);
83}
84
85static int
86savage_bci_wait_fifo_s4(drm_savage_private_t *dev_priv, unsigned int n)
87{
88 uint32_t maxUsed = dev_priv->cob_size + SAVAGE_BCI_FIFO_SIZE - n;
89 uint32_t status;
90 int i;
91
92 for (i = 0; i < SAVAGE_DEFAULT_USEC_TIMEOUT; i++) {
93 status = SAVAGE_READ(SAVAGE_ALT_STATUS_WORD0);
94 if ((status & SAVAGE_FIFO_USED_MASK_S4) <= maxUsed)
95 return 0;
96 DRM_UDELAY(1);
97 }
98
99#if SAVAGE_BCI_DEBUG
100 DRM_ERROR("failed!\n");
101 DRM_INFO(" status=0x%08x\n", status);
102#endif
103 return DRM_ERR(EBUSY);
104}
105
106/*
107 * Waiting for events.
108 *
109 * The BIOSresets the event tag to 0 on mode changes. Therefore we
110 * never emit 0 to the event tag. If we find a 0 event tag we know the
111 * BIOS stomped on it and return success assuming that the BIOS waited
112 * for engine idle.
113 *
114 * Note: if the Xserver uses the event tag it has to follow the same
115 * rule. Otherwise there may be glitches every 2^16 events.
116 */
117static int
118savage_bci_wait_event_shadow(drm_savage_private_t *dev_priv, uint16_t e)
119{
120 uint32_t status;
121 int i;
122
123 for (i = 0; i < SAVAGE_EVENT_USEC_TIMEOUT; i++) {
124 DRM_MEMORYBARRIER();
125 status = dev_priv->status_ptr[1];
126 if ((((status & 0xffff) - e) & 0xffff) <= 0x7fff ||
127 (status & 0xffff) == 0)
128 return 0;
129 DRM_UDELAY(1);
130 }
131
132#if SAVAGE_BCI_DEBUG
133 DRM_ERROR("failed!\n");
134 DRM_INFO(" status=0x%08x, e=0x%04x\n", status, e);
135#endif
136
137 return DRM_ERR(EBUSY);
138}
139
140static int
141savage_bci_wait_event_reg(drm_savage_private_t *dev_priv, uint16_t e)
142{
143 uint32_t status;
144 int i;
145
146 for (i = 0; i < SAVAGE_EVENT_USEC_TIMEOUT; i++) {
147 status = SAVAGE_READ(SAVAGE_STATUS_WORD1);
148 if ((((status & 0xffff) - e) & 0xffff) <= 0x7fff ||
149 (status & 0xffff) == 0)
150 return 0;
151 DRM_UDELAY(1);
152 }
153
154#if SAVAGE_BCI_DEBUG
155 DRM_ERROR("failed!\n");
156 DRM_INFO(" status=0x%08x, e=0x%04x\n", status, e);
157#endif
158
159 return DRM_ERR(EBUSY);
160}
161
162uint16_t savage_bci_emit_event(drm_savage_private_t *dev_priv,
163 unsigned int flags)
164{
165 uint16_t count;
166 BCI_LOCALS;
167
168 if (dev_priv->status_ptr) {
169 /* coordinate with Xserver */
170 count = dev_priv->status_ptr[1023];
171 if (count < dev_priv->event_counter)
172 dev_priv->event_wrap++;
173 } else {
174 count = dev_priv->event_counter;
175 }
176 count = (count + 1) & 0xffff;
177 if (count == 0) {
178 count++; /* See the comment above savage_wait_event_*. */
179 dev_priv->event_wrap++;
180 }
181 dev_priv->event_counter = count;
182 if (dev_priv->status_ptr)
183 dev_priv->status_ptr[1023] = (uint32_t)count;
184
185 if ((flags & (SAVAGE_WAIT_2D | SAVAGE_WAIT_3D))) {
186 unsigned int wait_cmd = BCI_CMD_WAIT;
187 if ((flags & SAVAGE_WAIT_2D))
188 wait_cmd |= BCI_CMD_WAIT_2D;
189 if ((flags & SAVAGE_WAIT_3D))
190 wait_cmd |= BCI_CMD_WAIT_3D;
191 BEGIN_BCI(2);
192 BCI_WRITE(wait_cmd);
193 } else {
194 BEGIN_BCI(1);
195 }
196 BCI_WRITE(BCI_CMD_UPDATE_EVENT_TAG | (uint32_t)count);
197
198 return count;
199}
200
201/*
202 * Freelist management
203 */
204static int savage_freelist_init(drm_device_t *dev)
205{
206 drm_savage_private_t *dev_priv = dev->dev_private;
207 drm_device_dma_t *dma = dev->dma;
208 drm_buf_t *buf;
209 drm_savage_buf_priv_t *entry;
210 int i;
211 DRM_DEBUG("count=%d\n", dma->buf_count);
212
213 dev_priv->head.next = &dev_priv->tail;
214 dev_priv->head.prev = NULL;
215 dev_priv->head.buf = NULL;
216
217 dev_priv->tail.next = NULL;
218 dev_priv->tail.prev = &dev_priv->head;
219 dev_priv->tail.buf = NULL;
220
221 for (i = 0; i < dma->buf_count; i++) {
222 buf = dma->buflist[i];
223 entry = buf->dev_private;
224
225 SET_AGE(&entry->age, 0, 0);
226 entry->buf = buf;
227
228 entry->next = dev_priv->head.next;
229 entry->prev = &dev_priv->head;
230 dev_priv->head.next->prev = entry;
231 dev_priv->head.next = entry;
232 }
233
234 return 0;
235}
236
237static drm_buf_t *savage_freelist_get(drm_device_t *dev)
238{
239 drm_savage_private_t *dev_priv = dev->dev_private;
240 drm_savage_buf_priv_t *tail = dev_priv->tail.prev;
241 uint16_t event;
242 unsigned int wrap;
243 DRM_DEBUG("\n");
244
245 UPDATE_EVENT_COUNTER();
246 if (dev_priv->status_ptr)
247 event = dev_priv->status_ptr[1] & 0xffff;
248 else
249 event = SAVAGE_READ(SAVAGE_STATUS_WORD1) & 0xffff;
250 wrap = dev_priv->event_wrap;
251 if (event > dev_priv->event_counter)
252 wrap--; /* hardware hasn't passed the last wrap yet */
253
254 DRM_DEBUG(" tail=0x%04x %d\n", tail->age.event, tail->age.wrap);
255 DRM_DEBUG(" head=0x%04x %d\n", event, wrap);
256
257 if (tail->buf && (TEST_AGE(&tail->age, event, wrap) || event == 0)) {
258 drm_savage_buf_priv_t *next = tail->next;
259 drm_savage_buf_priv_t *prev = tail->prev;
260 prev->next = next;
261 next->prev = prev;
262 tail->next = tail->prev = NULL;
263 return tail->buf;
264 }
265
266 DRM_DEBUG("returning NULL, tail->buf=%p!\n", tail->buf);
267 return NULL;
268}
269
270void savage_freelist_put(drm_device_t *dev, drm_buf_t *buf)
271{
272 drm_savage_private_t *dev_priv = dev->dev_private;
273 drm_savage_buf_priv_t *entry = buf->dev_private, *prev, *next;
274
275 DRM_DEBUG("age=0x%04x wrap=%d\n", entry->age.event, entry->age.wrap);
276
277 if (entry->next != NULL || entry->prev != NULL) {
278 DRM_ERROR("entry already on freelist.\n");
279 return;
280 }
281
282 prev = &dev_priv->head;
283 next = prev->next;
284 prev->next = entry;
285 next->prev = entry;
286 entry->prev = prev;
287 entry->next = next;
288}
289
290/*
291 * Command DMA
292 */
293static int savage_dma_init(drm_savage_private_t *dev_priv)
294{
295 unsigned int i;
296
297 dev_priv->nr_dma_pages = dev_priv->cmd_dma->size /
298 (SAVAGE_DMA_PAGE_SIZE*4);
299 dev_priv->dma_pages = drm_alloc(sizeof(drm_savage_dma_page_t) *
300 dev_priv->nr_dma_pages,
301 DRM_MEM_DRIVER);
302 if (dev_priv->dma_pages == NULL)
303 return DRM_ERR(ENOMEM);
304
305 for (i = 0; i < dev_priv->nr_dma_pages; ++i) {
306 SET_AGE(&dev_priv->dma_pages[i].age, 0, 0);
307 dev_priv->dma_pages[i].used = 0;
308 dev_priv->dma_pages[i].flushed = 0;
309 }
310 SET_AGE(&dev_priv->last_dma_age, 0, 0);
311
312 dev_priv->first_dma_page = 0;
313 dev_priv->current_dma_page = 0;
314
315 return 0;
316}
317
318void savage_dma_reset(drm_savage_private_t *dev_priv)
319{
320 uint16_t event;
321 unsigned int wrap, i;
322 event = savage_bci_emit_event(dev_priv, 0);
323 wrap = dev_priv->event_wrap;
324 for (i = 0; i < dev_priv->nr_dma_pages; ++i) {
325 SET_AGE(&dev_priv->dma_pages[i].age, event, wrap);
326 dev_priv->dma_pages[i].used = 0;
327 dev_priv->dma_pages[i].flushed = 0;
328 }
329 SET_AGE(&dev_priv->last_dma_age, event, wrap);
330 dev_priv->first_dma_page = dev_priv->current_dma_page = 0;
331}
332
333void savage_dma_wait(drm_savage_private_t *dev_priv, unsigned int page)
334{
335 uint16_t event;
336 unsigned int wrap;
337
338 /* Faked DMA buffer pages don't age. */
339 if (dev_priv->cmd_dma == &dev_priv->fake_dma)
340 return;
341
342 UPDATE_EVENT_COUNTER();
343 if (dev_priv->status_ptr)
344 event = dev_priv->status_ptr[1] & 0xffff;
345 else
346 event = SAVAGE_READ(SAVAGE_STATUS_WORD1) & 0xffff;
347 wrap = dev_priv->event_wrap;
348 if (event > dev_priv->event_counter)
349 wrap--; /* hardware hasn't passed the last wrap yet */
350
351 if (dev_priv->dma_pages[page].age.wrap > wrap ||
352 (dev_priv->dma_pages[page].age.wrap == wrap &&
353 dev_priv->dma_pages[page].age.event > event)) {
354 if (dev_priv->wait_evnt(dev_priv,
355 dev_priv->dma_pages[page].age.event)
356 < 0)
357 DRM_ERROR("wait_evnt failed!\n");
358 }
359}
360
361uint32_t *savage_dma_alloc(drm_savage_private_t *dev_priv, unsigned int n)
362{
363 unsigned int cur = dev_priv->current_dma_page;
364 unsigned int rest = SAVAGE_DMA_PAGE_SIZE -
365 dev_priv->dma_pages[cur].used;
366 unsigned int nr_pages = (n - rest + SAVAGE_DMA_PAGE_SIZE-1) /
367 SAVAGE_DMA_PAGE_SIZE;
368 uint32_t *dma_ptr;
369 unsigned int i;
370
371 DRM_DEBUG("cur=%u, cur->used=%u, n=%u, rest=%u, nr_pages=%u\n",
372 cur, dev_priv->dma_pages[cur].used, n, rest, nr_pages);
373
374 if (cur + nr_pages < dev_priv->nr_dma_pages) {
375 dma_ptr = (uint32_t *)dev_priv->cmd_dma->handle +
376 cur*SAVAGE_DMA_PAGE_SIZE +
377 dev_priv->dma_pages[cur].used;
378 if (n < rest)
379 rest = n;
380 dev_priv->dma_pages[cur].used += rest;
381 n -= rest;
382 cur++;
383 } else {
384 dev_priv->dma_flush(dev_priv);
385 nr_pages = (n + SAVAGE_DMA_PAGE_SIZE-1) / SAVAGE_DMA_PAGE_SIZE;
386 for (i = cur; i < dev_priv->nr_dma_pages; ++i) {
387 dev_priv->dma_pages[i].age = dev_priv->last_dma_age;
388 dev_priv->dma_pages[i].used = 0;
389 dev_priv->dma_pages[i].flushed = 0;
390 }
391 dma_ptr = (uint32_t *)dev_priv->cmd_dma->handle;
392 dev_priv->first_dma_page = cur = 0;
393 }
394 for (i = cur; nr_pages > 0; ++i, --nr_pages) {
395#if SAVAGE_DMA_DEBUG
396 if (dev_priv->dma_pages[i].used) {
397 DRM_ERROR("unflushed page %u: used=%u\n",
398 i, dev_priv->dma_pages[i].used);
399 }
400#endif
401 if (n > SAVAGE_DMA_PAGE_SIZE)
402 dev_priv->dma_pages[i].used = SAVAGE_DMA_PAGE_SIZE;
403 else
404 dev_priv->dma_pages[i].used = n;
405 n -= SAVAGE_DMA_PAGE_SIZE;
406 }
407 dev_priv->current_dma_page = --i;
408
409 DRM_DEBUG("cur=%u, cur->used=%u, n=%u\n",
410 i, dev_priv->dma_pages[i].used, n);
411
412 savage_dma_wait(dev_priv, dev_priv->current_dma_page);
413
414 return dma_ptr;
415}
416
417static void savage_dma_flush(drm_savage_private_t *dev_priv)
418{
419 unsigned int first = dev_priv->first_dma_page;
420 unsigned int cur = dev_priv->current_dma_page;
421 uint16_t event;
422 unsigned int wrap, pad, align, len, i;
423 unsigned long phys_addr;
424 BCI_LOCALS;
425
426 if (first == cur &&
427 dev_priv->dma_pages[cur].used == dev_priv->dma_pages[cur].flushed)
428 return;
429
430 /* pad length to multiples of 2 entries
431 * align start of next DMA block to multiles of 8 entries */
432 pad = -dev_priv->dma_pages[cur].used & 1;
433 align = -(dev_priv->dma_pages[cur].used + pad) & 7;
434
435 DRM_DEBUG("first=%u, cur=%u, first->flushed=%u, cur->used=%u, "
436 "pad=%u, align=%u\n",
437 first, cur, dev_priv->dma_pages[first].flushed,
438 dev_priv->dma_pages[cur].used, pad, align);
439
440 /* pad with noops */
441 if (pad) {
442 uint32_t *dma_ptr = (uint32_t *)dev_priv->cmd_dma->handle +
443 cur * SAVAGE_DMA_PAGE_SIZE +
444 dev_priv->dma_pages[cur].used;
445 dev_priv->dma_pages[cur].used += pad;
446 while(pad != 0) {
447 *dma_ptr++ = BCI_CMD_WAIT;
448 pad--;
449 }
450 }
451
452 DRM_MEMORYBARRIER();
453
454 /* do flush ... */
455 phys_addr = dev_priv->cmd_dma->offset +
456 (first * SAVAGE_DMA_PAGE_SIZE +
457 dev_priv->dma_pages[first].flushed) * 4;
458 len = (cur - first) * SAVAGE_DMA_PAGE_SIZE +
459 dev_priv->dma_pages[cur].used -
460 dev_priv->dma_pages[first].flushed;
461
462 DRM_DEBUG("phys_addr=%lx, len=%u\n",
463 phys_addr | dev_priv->dma_type, len);
464
465 BEGIN_BCI(3);
466 BCI_SET_REGISTERS(SAVAGE_DMABUFADDR, 1);
467 BCI_WRITE(phys_addr | dev_priv->dma_type);
468 BCI_DMA(len);
469
470 /* fix alignment of the start of the next block */
471 dev_priv->dma_pages[cur].used += align;
472
473 /* age DMA pages */
474 event = savage_bci_emit_event(dev_priv, 0);
475 wrap = dev_priv->event_wrap;
476 for (i = first; i < cur; ++i) {
477 SET_AGE(&dev_priv->dma_pages[i].age, event, wrap);
478 dev_priv->dma_pages[i].used = 0;
479 dev_priv->dma_pages[i].flushed = 0;
480 }
481 /* age the current page only when it's full */
482 if (dev_priv->dma_pages[cur].used == SAVAGE_DMA_PAGE_SIZE) {
483 SET_AGE(&dev_priv->dma_pages[cur].age, event, wrap);
484 dev_priv->dma_pages[cur].used = 0;
485 dev_priv->dma_pages[cur].flushed = 0;
486 /* advance to next page */
487 cur++;
488 if (cur == dev_priv->nr_dma_pages)
489 cur = 0;
490 dev_priv->first_dma_page = dev_priv->current_dma_page = cur;
491 } else {
492 dev_priv->first_dma_page = cur;
493 dev_priv->dma_pages[cur].flushed = dev_priv->dma_pages[i].used;
494 }
495 SET_AGE(&dev_priv->last_dma_age, event, wrap);
496
497 DRM_DEBUG("first=cur=%u, cur->used=%u, cur->flushed=%u\n", cur,
498 dev_priv->dma_pages[cur].used,
499 dev_priv->dma_pages[cur].flushed);
500}
501
502static void savage_fake_dma_flush(drm_savage_private_t *dev_priv)
503{
504 unsigned int i, j;
505 BCI_LOCALS;
506
507 if (dev_priv->first_dma_page == dev_priv->current_dma_page &&
508 dev_priv->dma_pages[dev_priv->current_dma_page].used == 0)
509 return;
510
511 DRM_DEBUG("first=%u, cur=%u, cur->used=%u\n",
512 dev_priv->first_dma_page, dev_priv->current_dma_page,
513 dev_priv->dma_pages[dev_priv->current_dma_page].used);
514
515 for (i = dev_priv->first_dma_page;
516 i <= dev_priv->current_dma_page && dev_priv->dma_pages[i].used;
517 ++i) {
518 uint32_t *dma_ptr = (uint32_t *)dev_priv->cmd_dma->handle +
519 i * SAVAGE_DMA_PAGE_SIZE;
520#if SAVAGE_DMA_DEBUG
521 /* Sanity check: all pages except the last one must be full. */
522 if (i < dev_priv->current_dma_page &&
523 dev_priv->dma_pages[i].used != SAVAGE_DMA_PAGE_SIZE) {
524 DRM_ERROR("partial DMA page %u: used=%u",
525 i, dev_priv->dma_pages[i].used);
526 }
527#endif
528 BEGIN_BCI(dev_priv->dma_pages[i].used);
529 for (j = 0; j < dev_priv->dma_pages[i].used; ++j) {
530 BCI_WRITE(dma_ptr[j]);
531 }
532 dev_priv->dma_pages[i].used = 0;
533 }
534
535 /* reset to first page */
536 dev_priv->first_dma_page = dev_priv->current_dma_page = 0;
537}
538
539/*
540 * Initalize mappings. On Savage4 and SavageIX the alignment
541 * and size of the aperture is not suitable for automatic MTRR setup
542 * in drm_addmap. Therefore we do it manually before the maps are
543 * initialized. We also need to take care of deleting the MTRRs in
544 * postcleanup.
545 */
546int savage_preinit(drm_device_t *dev, unsigned long chipset)
547{
548 drm_savage_private_t *dev_priv;
549 unsigned long mmio_base, fb_base, fb_size, aperture_base;
550 /* fb_rsrc and aper_rsrc aren't really used currently, but still exist
551 * in case we decide we need information on the BAR for BSD in the
552 * future.
553 */
554 unsigned int fb_rsrc, aper_rsrc;
555 int ret = 0;
556
557 dev_priv = drm_alloc(sizeof(drm_savage_private_t), DRM_MEM_DRIVER);
558 if (dev_priv == NULL)
559 return DRM_ERR(ENOMEM);
560
561 memset(dev_priv, 0, sizeof(drm_savage_private_t));
562 dev->dev_private = (void *)dev_priv;
563 dev_priv->chipset = (enum savage_family)chipset;
564
565 dev_priv->mtrr[0].handle = -1;
566 dev_priv->mtrr[1].handle = -1;
567 dev_priv->mtrr[2].handle = -1;
568 if (S3_SAVAGE3D_SERIES(dev_priv->chipset)) {
569 fb_rsrc = 0;
570 fb_base = drm_get_resource_start(dev, 0);
571 fb_size = SAVAGE_FB_SIZE_S3;
572 mmio_base = fb_base + SAVAGE_FB_SIZE_S3;
573 aper_rsrc = 0;
574 aperture_base = fb_base + SAVAGE_APERTURE_OFFSET;
575 /* this should always be true */
576 if (drm_get_resource_len(dev, 0) == 0x08000000) {
577 /* Don't make MMIO write-cobining! We need 3
578 * MTRRs. */
579 dev_priv->mtrr[0].base = fb_base;
580 dev_priv->mtrr[0].size = 0x01000000;
581 dev_priv->mtrr[0].handle = mtrr_add(
582 dev_priv->mtrr[0].base, dev_priv->mtrr[0].size,
583 MTRR_TYPE_WRCOMB, 1);
584 dev_priv->mtrr[1].base = fb_base+0x02000000;
585 dev_priv->mtrr[1].size = 0x02000000;
586 dev_priv->mtrr[1].handle = mtrr_add(
587 dev_priv->mtrr[1].base, dev_priv->mtrr[1].size,
588 MTRR_TYPE_WRCOMB, 1);
589 dev_priv->mtrr[2].base = fb_base+0x04000000;
590 dev_priv->mtrr[2].size = 0x04000000;
591 dev_priv->mtrr[2].handle = mtrr_add(
592 dev_priv->mtrr[2].base, dev_priv->mtrr[2].size,
593 MTRR_TYPE_WRCOMB, 1);
594 } else {
595 DRM_ERROR("strange pci_resource_len %08lx\n",
596 drm_get_resource_len(dev, 0));
597 }
598 } else if (chipset != S3_SUPERSAVAGE && chipset != S3_SAVAGE2000) {
599 mmio_base = drm_get_resource_start(dev, 0);
600 fb_rsrc = 1;
601 fb_base = drm_get_resource_start(dev, 1);
602 fb_size = SAVAGE_FB_SIZE_S4;
603 aper_rsrc = 1;
604 aperture_base = fb_base + SAVAGE_APERTURE_OFFSET;
605 /* this should always be true */
606 if (drm_get_resource_len(dev, 1) == 0x08000000) {
607 /* Can use one MTRR to cover both fb and
608 * aperture. */
609 dev_priv->mtrr[0].base = fb_base;
610 dev_priv->mtrr[0].size = 0x08000000;
611 dev_priv->mtrr[0].handle = mtrr_add(
612 dev_priv->mtrr[0].base, dev_priv->mtrr[0].size,
613 MTRR_TYPE_WRCOMB, 1);
614 } else {
615 DRM_ERROR("strange pci_resource_len %08lx\n",
616 drm_get_resource_len(dev, 1));
617 }
618 } else {
619 mmio_base = drm_get_resource_start(dev, 0);
620 fb_rsrc = 1;
621 fb_base = drm_get_resource_start(dev, 1);
622 fb_size = drm_get_resource_len(dev, 1);
623 aper_rsrc = 2;
624 aperture_base = drm_get_resource_start(dev, 2);
625 /* Automatic MTRR setup will do the right thing. */
626 }
627
628 ret = drm_addmap(dev, mmio_base, SAVAGE_MMIO_SIZE, _DRM_REGISTERS,
629 _DRM_READ_ONLY, &dev_priv->mmio);
630 if (ret)
631 return ret;
632
633 ret = drm_addmap(dev, fb_base, fb_size, _DRM_FRAME_BUFFER,
634 _DRM_WRITE_COMBINING, &dev_priv->fb);
635 if (ret)
636 return ret;
637
638 ret = drm_addmap(dev, aperture_base, SAVAGE_APERTURE_SIZE,
639 _DRM_FRAME_BUFFER, _DRM_WRITE_COMBINING,
640 &dev_priv->aperture);
641 if (ret)
642 return ret;
643
644 return ret;
645}
646
647/*
648 * Delete MTRRs and free device-private data.
649 */
650int savage_postcleanup(drm_device_t *dev)
651{
652 drm_savage_private_t *dev_priv = dev->dev_private;
653 int i;
654
655 for (i = 0; i < 3; ++i)
656 if (dev_priv->mtrr[i].handle >= 0)
657 mtrr_del(dev_priv->mtrr[i].handle,
658 dev_priv->mtrr[i].base,
659 dev_priv->mtrr[i].size);
660
661 drm_free(dev_priv, sizeof(drm_savage_private_t), DRM_MEM_DRIVER);
662
663 return 0;
664}
665
666static int savage_do_init_bci(drm_device_t *dev, drm_savage_init_t *init)
667{
668 drm_savage_private_t *dev_priv = dev->dev_private;
669
670 if (init->fb_bpp != 16 && init->fb_bpp != 32) {
671 DRM_ERROR("invalid frame buffer bpp %d!\n", init->fb_bpp);
672 return DRM_ERR(EINVAL);
673 }
674 if (init->depth_bpp != 16 && init->depth_bpp != 32) {
675 DRM_ERROR("invalid depth buffer bpp %d!\n", init->fb_bpp);
676 return DRM_ERR(EINVAL);
677 }
678 if (init->dma_type != SAVAGE_DMA_AGP &&
679 init->dma_type != SAVAGE_DMA_PCI) {
680 DRM_ERROR("invalid dma memory type %d!\n", init->dma_type);
681 return DRM_ERR(EINVAL);
682 }
683
684 dev_priv->cob_size = init->cob_size;
685 dev_priv->bci_threshold_lo = init->bci_threshold_lo;
686 dev_priv->bci_threshold_hi = init->bci_threshold_hi;
687 dev_priv->dma_type = init->dma_type;
688
689 dev_priv->fb_bpp = init->fb_bpp;
690 dev_priv->front_offset = init->front_offset;
691 dev_priv->front_pitch = init->front_pitch;
692 dev_priv->back_offset = init->back_offset;
693 dev_priv->back_pitch = init->back_pitch;
694 dev_priv->depth_bpp = init->depth_bpp;
695 dev_priv->depth_offset = init->depth_offset;
696 dev_priv->depth_pitch = init->depth_pitch;
697
698 dev_priv->texture_offset = init->texture_offset;
699 dev_priv->texture_size = init->texture_size;
700
701 DRM_GETSAREA();
702 if (!dev_priv->sarea) {
703 DRM_ERROR("could not find sarea!\n");
704 savage_do_cleanup_bci(dev);
705 return DRM_ERR(EINVAL);
706 }
707 if (init->status_offset != 0) {
708 dev_priv->status = drm_core_findmap(dev, init->status_offset);
709 if (!dev_priv->status) {
710 DRM_ERROR("could not find shadow status region!\n");
711 savage_do_cleanup_bci(dev);
712 return DRM_ERR(EINVAL);
713 }
714 } else {
715 dev_priv->status = NULL;
716 }
717 if (dev_priv->dma_type == SAVAGE_DMA_AGP && init->buffers_offset) {
718 dev->agp_buffer_map = drm_core_findmap(dev,
719 init->buffers_offset);
720 if (!dev->agp_buffer_map) {
721 DRM_ERROR("could not find DMA buffer region!\n");
722 savage_do_cleanup_bci(dev);
723 return DRM_ERR(EINVAL);
724 }
725 drm_core_ioremap(dev->agp_buffer_map, dev);
726 if (!dev->agp_buffer_map) {
727 DRM_ERROR("failed to ioremap DMA buffer region!\n");
728 savage_do_cleanup_bci(dev);
729 return DRM_ERR(ENOMEM);
730 }
731 }
732 if (init->agp_textures_offset) {
733 dev_priv->agp_textures =
734 drm_core_findmap(dev, init->agp_textures_offset);
735 if (!dev_priv->agp_textures) {
736 DRM_ERROR("could not find agp texture region!\n");
737 savage_do_cleanup_bci(dev);
738 return DRM_ERR(EINVAL);
739 }
740 } else {
741 dev_priv->agp_textures = NULL;
742 }
743
744 if (init->cmd_dma_offset) {
745 if (S3_SAVAGE3D_SERIES(dev_priv->chipset)) {
746 DRM_ERROR("command DMA not supported on "
747 "Savage3D/MX/IX.\n");
748 savage_do_cleanup_bci(dev);
749 return DRM_ERR(EINVAL);
750 }
751 if (dev->dma && dev->dma->buflist) {
752 DRM_ERROR("command and vertex DMA not supported "
753 "at the same time.\n");
754 savage_do_cleanup_bci(dev);
755 return DRM_ERR(EINVAL);
756 }
757 dev_priv->cmd_dma = drm_core_findmap(dev, init->cmd_dma_offset);
758 if (!dev_priv->cmd_dma) {
759 DRM_ERROR("could not find command DMA region!\n");
760 savage_do_cleanup_bci(dev);
761 return DRM_ERR(EINVAL);
762 }
763 if (dev_priv->dma_type == SAVAGE_DMA_AGP) {
764 if (dev_priv->cmd_dma->type != _DRM_AGP) {
765 DRM_ERROR("AGP command DMA region is not a "
766 "_DRM_AGP map!\n");
767 savage_do_cleanup_bci(dev);
768 return DRM_ERR(EINVAL);
769 }
770 drm_core_ioremap(dev_priv->cmd_dma, dev);
771 if (!dev_priv->cmd_dma->handle) {
772 DRM_ERROR("failed to ioremap command "
773 "DMA region!\n");
774 savage_do_cleanup_bci(dev);
775 return DRM_ERR(ENOMEM);
776 }
777 } else if (dev_priv->cmd_dma->type != _DRM_CONSISTENT) {
778 DRM_ERROR("PCI command DMA region is not a "
779 "_DRM_CONSISTENT map!\n");
780 savage_do_cleanup_bci(dev);
781 return DRM_ERR(EINVAL);
782 }
783 } else {
784 dev_priv->cmd_dma = NULL;
785 }
786
787 dev_priv->dma_flush = savage_dma_flush;
788 if (!dev_priv->cmd_dma) {
789 DRM_DEBUG("falling back to faked command DMA.\n");
790 dev_priv->fake_dma.offset = 0;
791 dev_priv->fake_dma.size = SAVAGE_FAKE_DMA_SIZE;
792 dev_priv->fake_dma.type = _DRM_SHM;
793 dev_priv->fake_dma.handle = drm_alloc(SAVAGE_FAKE_DMA_SIZE,
794 DRM_MEM_DRIVER);
795 if (!dev_priv->fake_dma.handle) {
796 DRM_ERROR("could not allocate faked DMA buffer!\n");
797 savage_do_cleanup_bci(dev);
798 return DRM_ERR(ENOMEM);
799 }
800 dev_priv->cmd_dma = &dev_priv->fake_dma;
801 dev_priv->dma_flush = savage_fake_dma_flush;
802 }
803
804 dev_priv->sarea_priv =
805 (drm_savage_sarea_t *)((uint8_t *)dev_priv->sarea->handle +
806 init->sarea_priv_offset);
807
808 /* setup bitmap descriptors */
809 {
810 unsigned int color_tile_format;
811 unsigned int depth_tile_format;
812 unsigned int front_stride, back_stride, depth_stride;
813 if (dev_priv->chipset <= S3_SAVAGE4) {
814 color_tile_format = dev_priv->fb_bpp == 16 ?
815 SAVAGE_BD_TILE_16BPP : SAVAGE_BD_TILE_32BPP;
816 depth_tile_format = dev_priv->depth_bpp == 16 ?
817 SAVAGE_BD_TILE_16BPP : SAVAGE_BD_TILE_32BPP;
818 } else {
819 color_tile_format = SAVAGE_BD_TILE_DEST;
820 depth_tile_format = SAVAGE_BD_TILE_DEST;
821 }
822 front_stride = dev_priv->front_pitch / (dev_priv->fb_bpp/8);
823 back_stride = dev_priv-> back_pitch / (dev_priv->fb_bpp/8);
824 depth_stride = dev_priv->depth_pitch / (dev_priv->depth_bpp/8);
825
826 dev_priv->front_bd = front_stride | SAVAGE_BD_BW_DISABLE |
827 (dev_priv->fb_bpp << SAVAGE_BD_BPP_SHIFT) |
828 (color_tile_format << SAVAGE_BD_TILE_SHIFT);
829
830 dev_priv-> back_bd = back_stride | SAVAGE_BD_BW_DISABLE |
831 (dev_priv->fb_bpp << SAVAGE_BD_BPP_SHIFT) |
832 (color_tile_format << SAVAGE_BD_TILE_SHIFT);
833
834 dev_priv->depth_bd = depth_stride | SAVAGE_BD_BW_DISABLE |
835 (dev_priv->depth_bpp << SAVAGE_BD_BPP_SHIFT) |
836 (depth_tile_format << SAVAGE_BD_TILE_SHIFT);
837 }
838
839 /* setup status and bci ptr */
840 dev_priv->event_counter = 0;
841 dev_priv->event_wrap = 0;
842 dev_priv->bci_ptr = (volatile uint32_t *)
843 ((uint8_t *)dev_priv->mmio->handle + SAVAGE_BCI_OFFSET);
844 if (S3_SAVAGE3D_SERIES(dev_priv->chipset)) {
845 dev_priv->status_used_mask = SAVAGE_FIFO_USED_MASK_S3D;
846 } else {
847 dev_priv->status_used_mask = SAVAGE_FIFO_USED_MASK_S4;
848 }
849 if (dev_priv->status != NULL) {
850 dev_priv->status_ptr =
851 (volatile uint32_t *)dev_priv->status->handle;
852 dev_priv->wait_fifo = savage_bci_wait_fifo_shadow;
853 dev_priv->wait_evnt = savage_bci_wait_event_shadow;
854 dev_priv->status_ptr[1023] = dev_priv->event_counter;
855 } else {
856 dev_priv->status_ptr = NULL;
857 if (S3_SAVAGE3D_SERIES(dev_priv->chipset)) {
858 dev_priv->wait_fifo = savage_bci_wait_fifo_s3d;
859 } else {
860 dev_priv->wait_fifo = savage_bci_wait_fifo_s4;
861 }
862 dev_priv->wait_evnt = savage_bci_wait_event_reg;
863 }
864
865 /* cliprect functions */
866 if (S3_SAVAGE3D_SERIES(dev_priv->chipset))
867 dev_priv->emit_clip_rect = savage_emit_clip_rect_s3d;
868 else
869 dev_priv->emit_clip_rect = savage_emit_clip_rect_s4;
870
871 if (savage_freelist_init(dev) < 0) {
872 DRM_ERROR("could not initialize freelist\n");
873 savage_do_cleanup_bci(dev);
874 return DRM_ERR(ENOMEM);
875 }
876
877 if (savage_dma_init(dev_priv) < 0) {
878 DRM_ERROR("could not initialize command DMA\n");
879 savage_do_cleanup_bci(dev);
880 return DRM_ERR(ENOMEM);
881 }
882
883 return 0;
884}
885
886int savage_do_cleanup_bci(drm_device_t *dev)
887{
888 drm_savage_private_t *dev_priv = dev->dev_private;
889
890 if (dev_priv->cmd_dma == &dev_priv->fake_dma) {
891 if (dev_priv->fake_dma.handle)
892 drm_free(dev_priv->fake_dma.handle,
893 SAVAGE_FAKE_DMA_SIZE, DRM_MEM_DRIVER);
894 } else if (dev_priv->cmd_dma && dev_priv->cmd_dma->handle &&
895 dev_priv->cmd_dma->type == _DRM_AGP &&
896 dev_priv->dma_type == SAVAGE_DMA_AGP)
897 drm_core_ioremapfree(dev_priv->cmd_dma, dev);
898
899 if (dev_priv->dma_type == SAVAGE_DMA_AGP &&
900 dev->agp_buffer_map && dev->agp_buffer_map->handle) {
901 drm_core_ioremapfree(dev->agp_buffer_map, dev);
902 /* make sure the next instance (which may be running
903 * in PCI mode) doesn't try to use an old
904 * agp_buffer_map. */
905 dev->agp_buffer_map = NULL;
906 }
907
908 if (dev_priv->dma_pages)
909 drm_free(dev_priv->dma_pages,
910 sizeof(drm_savage_dma_page_t)*dev_priv->nr_dma_pages,
911 DRM_MEM_DRIVER);
912
913 return 0;
914}
915
916static int savage_bci_init(DRM_IOCTL_ARGS)
917{
918 DRM_DEVICE;
919 drm_savage_init_t init;
920
921 LOCK_TEST_WITH_RETURN(dev, filp);
922
923 DRM_COPY_FROM_USER_IOCTL(init, (drm_savage_init_t __user *)data,
924 sizeof(init));
925
926 switch (init.func) {
927 case SAVAGE_INIT_BCI:
928 return savage_do_init_bci(dev, &init);
929 case SAVAGE_CLEANUP_BCI:
930 return savage_do_cleanup_bci(dev);
931 }
932
933 return DRM_ERR(EINVAL);
934}
935
936static int savage_bci_event_emit(DRM_IOCTL_ARGS)
937{
938 DRM_DEVICE;
939 drm_savage_private_t *dev_priv = dev->dev_private;
940 drm_savage_event_emit_t event;
941
942 DRM_DEBUG("\n");
943
944 LOCK_TEST_WITH_RETURN(dev, filp);
945
946 DRM_COPY_FROM_USER_IOCTL(event, (drm_savage_event_emit_t __user *)data,
947 sizeof(event));
948
949 event.count = savage_bci_emit_event(dev_priv, event.flags);
950 event.count |= dev_priv->event_wrap << 16;
951 DRM_COPY_TO_USER_IOCTL(&((drm_savage_event_emit_t __user *)data)->count,
952 event.count, sizeof(event.count));
953 return 0;
954}
955
956static int savage_bci_event_wait(DRM_IOCTL_ARGS)
957{
958 DRM_DEVICE;
959 drm_savage_private_t *dev_priv = dev->dev_private;
960 drm_savage_event_wait_t event;
961 unsigned int event_e, hw_e;
962 unsigned int event_w, hw_w;
963
964 DRM_DEBUG("\n");
965
966 DRM_COPY_FROM_USER_IOCTL(event, (drm_savage_event_wait_t __user *)data,
967 sizeof(event));
968
969 UPDATE_EVENT_COUNTER();
970 if (dev_priv->status_ptr)
971 hw_e = dev_priv->status_ptr[1] & 0xffff;
972 else
973 hw_e = SAVAGE_READ(SAVAGE_STATUS_WORD1) & 0xffff;
974 hw_w = dev_priv->event_wrap;
975 if (hw_e > dev_priv->event_counter)
976 hw_w--; /* hardware hasn't passed the last wrap yet */
977
978 event_e = event.count & 0xffff;
979 event_w = event.count >> 16;
980
981 /* Don't need to wait if
982 * - event counter wrapped since the event was emitted or
983 * - the hardware has advanced up to or over the event to wait for.
984 */
985 if (event_w < hw_w || (event_w == hw_w && event_e <= hw_e) )
986 return 0;
987 else
988 return dev_priv->wait_evnt(dev_priv, event_e);
989}
990
991/*
992 * DMA buffer management
993 */
994
995static int savage_bci_get_buffers(DRMFILE filp, drm_device_t *dev, drm_dma_t *d)
996{
997 drm_buf_t *buf;
998 int i;
999
1000 for (i = d->granted_count; i < d->request_count; i++) {
1001 buf = savage_freelist_get(dev);
1002 if (!buf)
1003 return DRM_ERR(EAGAIN);
1004
1005 buf->filp = filp;
1006
1007 if (DRM_COPY_TO_USER(&d->request_indices[i],
1008 &buf->idx, sizeof(buf->idx)))
1009 return DRM_ERR(EFAULT);
1010 if (DRM_COPY_TO_USER(&d->request_sizes[i],
1011 &buf->total, sizeof(buf->total)))
1012 return DRM_ERR(EFAULT);
1013
1014 d->granted_count++;
1015 }
1016 return 0;
1017}
1018
1019int savage_bci_buffers(DRM_IOCTL_ARGS)
1020{
1021 DRM_DEVICE;
1022 drm_device_dma_t *dma = dev->dma;
1023 drm_dma_t d;
1024 int ret = 0;
1025
1026 LOCK_TEST_WITH_RETURN(dev, filp);
1027
1028 DRM_COPY_FROM_USER_IOCTL(d, (drm_dma_t __user *)data, sizeof(d));
1029
1030 /* Please don't send us buffers.
1031 */
1032 if (d.send_count != 0) {
1033 DRM_ERROR("Process %d trying to send %d buffers via drmDMA\n",
1034 DRM_CURRENTPID, d.send_count);
1035 return DRM_ERR(EINVAL);
1036 }
1037
1038 /* We'll send you buffers.
1039 */
1040 if (d.request_count < 0 || d.request_count > dma->buf_count) {
1041 DRM_ERROR("Process %d trying to get %d buffers (of %d max)\n",
1042 DRM_CURRENTPID, d.request_count, dma->buf_count);
1043 return DRM_ERR(EINVAL);
1044 }
1045
1046 d.granted_count = 0;
1047
1048 if (d.request_count) {
1049 ret = savage_bci_get_buffers(filp, dev, &d);
1050 }
1051
1052 DRM_COPY_TO_USER_IOCTL((drm_dma_t __user *)data, d, sizeof(d));
1053
1054 return ret;
1055}
1056
1057void savage_reclaim_buffers(drm_device_t *dev, DRMFILE filp) {
1058 drm_device_dma_t *dma = dev->dma;
1059 drm_savage_private_t *dev_priv = dev->dev_private;
1060 int i;
1061
1062 if (!dma)
1063 return;
1064 if (!dev_priv)
1065 return;
1066 if (!dma->buflist)
1067 return;
1068
1069 /*i830_flush_queue(dev);*/
1070
1071 for (i = 0; i < dma->buf_count; i++) {
1072 drm_buf_t *buf = dma->buflist[i];
1073 drm_savage_buf_priv_t *buf_priv = buf->dev_private;
1074
1075 if (buf->filp == filp && buf_priv &&
1076 buf_priv->next == NULL && buf_priv->prev == NULL) {
1077 uint16_t event;
1078 DRM_DEBUG("reclaimed from client\n");
1079 event = savage_bci_emit_event(dev_priv, SAVAGE_WAIT_3D);
1080 SET_AGE(&buf_priv->age, event, dev_priv->event_wrap);
1081 savage_freelist_put(dev, buf);
1082 }
1083 }
1084
1085 drm_core_reclaim_buffers(dev, filp);
1086}
1087
1088
1089drm_ioctl_desc_t savage_ioctls[] = {
1090 [DRM_IOCTL_NR(DRM_SAVAGE_BCI_INIT)] = {savage_bci_init, 1, 1},
1091 [DRM_IOCTL_NR(DRM_SAVAGE_BCI_CMDBUF)] = {savage_bci_cmdbuf, 1, 0},
1092 [DRM_IOCTL_NR(DRM_SAVAGE_BCI_EVENT_EMIT)] = {savage_bci_event_emit, 1, 0},
1093 [DRM_IOCTL_NR(DRM_SAVAGE_BCI_EVENT_WAIT)] = {savage_bci_event_wait, 1, 0},
1094};
1095
1096int savage_max_ioctl = DRM_ARRAY_SIZE(savage_ioctls);
diff --git a/drivers/char/drm/savage_drm.h b/drivers/char/drm/savage_drm.h
new file mode 100644
index 000000000000..6526c9aa7589
--- /dev/null
+++ b/drivers/char/drm/savage_drm.h
@@ -0,0 +1,209 @@
1/* savage_drm.h -- Public header for the savage driver
2 *
3 * Copyright 2004 Felix Kuehling
4 * All Rights Reserved.
5 *
6 * Permission is hereby granted, free of charge, to any person obtaining a
7 * copy of this software and associated documentation files (the "Software"),
8 * to deal in the Software without restriction, including without limitation
9 * the rights to use, copy, modify, merge, publish, distribute, sub license,
10 * and/or sell copies of the Software, and to permit persons to whom the
11 * Software is furnished to do so, subject to the following conditions:
12 *
13 * The above copyright notice and this permission notice (including the
14 * next paragraph) shall be included in all copies or substantial portions
15 * of the Software.
16 *
17 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
18 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
19 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
20 * NON-INFRINGEMENT. IN NO EVENT SHALL FELIX KUEHLING BE LIABLE FOR
21 * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF
22 * CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
23 * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
24 */
25
26#ifndef __SAVAGE_DRM_H__
27#define __SAVAGE_DRM_H__
28
29#ifndef __SAVAGE_SAREA_DEFINES__
30#define __SAVAGE_SAREA_DEFINES__
31
32/* 2 heaps (1 for card, 1 for agp), each divided into upto 128
33 * regions, subject to a minimum region size of (1<<16) == 64k.
34 *
35 * Clients may subdivide regions internally, but when sharing between
36 * clients, the region size is the minimum granularity.
37 */
38
39#define SAVAGE_CARD_HEAP 0
40#define SAVAGE_AGP_HEAP 1
41#define SAVAGE_NR_TEX_HEAPS 2
42#define SAVAGE_NR_TEX_REGIONS 16
43#define SAVAGE_LOG_MIN_TEX_REGION_SIZE 16
44
45#endif /* __SAVAGE_SAREA_DEFINES__ */
46
47typedef struct _drm_savage_sarea {
48 /* LRU lists for texture memory in agp space and on the card.
49 */
50 drm_tex_region_t texList[SAVAGE_NR_TEX_HEAPS][SAVAGE_NR_TEX_REGIONS+1];
51 unsigned int texAge[SAVAGE_NR_TEX_HEAPS];
52
53 /* Mechanism to validate card state.
54 */
55 int ctxOwner;
56} drm_savage_sarea_t, *drm_savage_sarea_ptr;
57
58/* Savage-specific ioctls
59 */
60#define DRM_SAVAGE_BCI_INIT 0x00
61#define DRM_SAVAGE_BCI_CMDBUF 0x01
62#define DRM_SAVAGE_BCI_EVENT_EMIT 0x02
63#define DRM_SAVAGE_BCI_EVENT_WAIT 0x03
64
65#define DRM_IOCTL_SAVAGE_INIT DRM_IOW( DRM_COMMAND_BASE + DRM_SAVAGE_BCI_INIT, drm_savage_init_t)
66#define DRM_IOCTL_SAVAGE_CMDBUF DRM_IOW( DRM_COMMAND_BASE + DRM_SAVAGE_BCI_CMDBUF, drm_savage_cmdbuf_t)
67#define DRM_IOCTL_SAVAGE_EVENT_EMIT DRM_IOWR(DRM_COMMAND_BASE + DRM_SAVAGE_BCI_EVENT_EMIT, drm_savage_event_emit_t)
68#define DRM_IOCTL_SAVAGE_EVENT_WAIT DRM_IOW( DRM_COMMAND_BASE + DRM_SAVAGE_BCI_EVENT_WAIT, drm_savage_event_wait_t)
69
70#define SAVAGE_DMA_PCI 1
71#define SAVAGE_DMA_AGP 3
72typedef struct drm_savage_init {
73 enum {
74 SAVAGE_INIT_BCI = 1,
75 SAVAGE_CLEANUP_BCI = 2
76 } func;
77 unsigned int sarea_priv_offset;
78
79 /* some parameters */
80 unsigned int cob_size;
81 unsigned int bci_threshold_lo, bci_threshold_hi;
82 unsigned int dma_type;
83
84 /* frame buffer layout */
85 unsigned int fb_bpp;
86 unsigned int front_offset, front_pitch;
87 unsigned int back_offset, back_pitch;
88 unsigned int depth_bpp;
89 unsigned int depth_offset, depth_pitch;
90
91 /* local textures */
92 unsigned int texture_offset;
93 unsigned int texture_size;
94
95 /* physical locations of non-permanent maps */
96 unsigned long status_offset;
97 unsigned long buffers_offset;
98 unsigned long agp_textures_offset;
99 unsigned long cmd_dma_offset;
100} drm_savage_init_t;
101
102typedef union drm_savage_cmd_header drm_savage_cmd_header_t;
103typedef struct drm_savage_cmdbuf {
104 /* command buffer in client's address space */
105 drm_savage_cmd_header_t __user *cmd_addr;
106 unsigned int size; /* size of the command buffer in 64bit units */
107
108 unsigned int dma_idx; /* DMA buffer index to use */
109 int discard; /* discard DMA buffer when done */
110 /* vertex buffer in client's address space */
111 unsigned int __user *vb_addr;
112 unsigned int vb_size; /* size of client vertex buffer in bytes */
113 unsigned int vb_stride; /* stride of vertices in 32bit words */
114 /* boxes in client's address space */
115 drm_clip_rect_t __user *box_addr;
116 unsigned int nbox; /* number of clipping boxes */
117} drm_savage_cmdbuf_t;
118
119#define SAVAGE_WAIT_2D 0x1 /* wait for 2D idle before updating event tag */
120#define SAVAGE_WAIT_3D 0x2 /* wait for 3D idle before updating event tag */
121#define SAVAGE_WAIT_IRQ 0x4 /* emit or wait for IRQ, not implemented yet */
122typedef struct drm_savage_event {
123 unsigned int count;
124 unsigned int flags;
125} drm_savage_event_emit_t, drm_savage_event_wait_t;
126
127/* Commands for the cmdbuf ioctl
128 */
129#define SAVAGE_CMD_STATE 0 /* a range of state registers */
130#define SAVAGE_CMD_DMA_PRIM 1 /* vertices from DMA buffer */
131#define SAVAGE_CMD_VB_PRIM 2 /* vertices from client vertex buffer */
132#define SAVAGE_CMD_DMA_IDX 3 /* indexed vertices from DMA buffer */
133#define SAVAGE_CMD_VB_IDX 4 /* indexed vertices client vertex buffer */
134#define SAVAGE_CMD_CLEAR 5 /* clear buffers */
135#define SAVAGE_CMD_SWAP 6 /* swap buffers */
136
137/* Primitive types
138*/
139#define SAVAGE_PRIM_TRILIST 0 /* triangle list */
140#define SAVAGE_PRIM_TRISTRIP 1 /* triangle strip */
141#define SAVAGE_PRIM_TRIFAN 2 /* triangle fan */
142#define SAVAGE_PRIM_TRILIST_201 3 /* reorder verts for correct flat
143 * shading on s3d */
144
145/* Skip flags (vertex format)
146 */
147#define SAVAGE_SKIP_Z 0x01
148#define SAVAGE_SKIP_W 0x02
149#define SAVAGE_SKIP_C0 0x04
150#define SAVAGE_SKIP_C1 0x08
151#define SAVAGE_SKIP_S0 0x10
152#define SAVAGE_SKIP_T0 0x20
153#define SAVAGE_SKIP_ST0 0x30
154#define SAVAGE_SKIP_S1 0x40
155#define SAVAGE_SKIP_T1 0x80
156#define SAVAGE_SKIP_ST1 0xc0
157#define SAVAGE_SKIP_ALL_S3D 0x3f
158#define SAVAGE_SKIP_ALL_S4 0xff
159
160/* Buffer names for clear command
161 */
162#define SAVAGE_FRONT 0x1
163#define SAVAGE_BACK 0x2
164#define SAVAGE_DEPTH 0x4
165
166/* 64-bit command header
167 */
168union drm_savage_cmd_header {
169 struct {
170 unsigned char cmd; /* command */
171 unsigned char pad0;
172 unsigned short pad1;
173 unsigned short pad2;
174 unsigned short pad3;
175 } cmd; /* generic */
176 struct {
177 unsigned char cmd;
178 unsigned char global; /* need idle engine? */
179 unsigned short count; /* number of consecutive registers */
180 unsigned short start; /* first register */
181 unsigned short pad3;
182 } state; /* SAVAGE_CMD_STATE */
183 struct {
184 unsigned char cmd;
185 unsigned char prim; /* primitive type */
186 unsigned short skip; /* vertex format (skip flags) */
187 unsigned short count; /* number of vertices */
188 unsigned short start; /* first vertex in DMA/vertex buffer */
189 } prim; /* SAVAGE_CMD_DMA_PRIM, SAVAGE_CMD_VB_PRIM */
190 struct {
191 unsigned char cmd;
192 unsigned char prim;
193 unsigned short skip;
194 unsigned short count; /* number of indices that follow */
195 unsigned short pad3;
196 } idx; /* SAVAGE_CMD_DMA_IDX, SAVAGE_CMD_VB_IDX */
197 struct {
198 unsigned char cmd;
199 unsigned char pad0;
200 unsigned short pad1;
201 unsigned int flags;
202 } clear0; /* SAVAGE_CMD_CLEAR */
203 struct {
204 unsigned int mask;
205 unsigned int value;
206 } clear1; /* SAVAGE_CMD_CLEAR data */
207};
208
209#endif
diff --git a/drivers/char/drm/savage_drv.c b/drivers/char/drm/savage_drv.c
new file mode 100644
index 000000000000..ac8d270427ca
--- /dev/null
+++ b/drivers/char/drm/savage_drv.c
@@ -0,0 +1,112 @@
1/* savage_drv.c -- Savage driver for Linux
2 *
3 * Copyright 2004 Felix Kuehling
4 * All Rights Reserved.
5 *
6 * Permission is hereby granted, free of charge, to any person obtaining a
7 * copy of this software and associated documentation files (the "Software"),
8 * to deal in the Software without restriction, including without limitation
9 * the rights to use, copy, modify, merge, publish, distribute, sub license,
10 * and/or sell copies of the Software, and to permit persons to whom the
11 * Software is furnished to do so, subject to the following conditions:
12 *
13 * The above copyright notice and this permission notice (including the
14 * next paragraph) shall be included in all copies or substantial portions
15 * of the Software.
16 *
17 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
18 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
19 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
20 * NON-INFRINGEMENT. IN NO EVENT SHALL FELIX KUEHLING BE LIABLE FOR
21 * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF
22 * CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
23 * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
24 */
25
26#include <linux/config.h>
27#include "drmP.h"
28#include "savage_drm.h"
29#include "savage_drv.h"
30
31#include "drm_pciids.h"
32
33static int postinit( struct drm_device *dev, unsigned long flags )
34{
35 DRM_INFO( "Initialized %s %d.%d.%d %s on minor %d: %s\n",
36 DRIVER_NAME,
37 DRIVER_MAJOR,
38 DRIVER_MINOR,
39 DRIVER_PATCHLEVEL,
40 DRIVER_DATE,
41 dev->primary.minor,
42 pci_pretty_name(dev->pdev)
43 );
44 return 0;
45}
46
47static int version( drm_version_t *version )
48{
49 int len;
50
51 version->version_major = DRIVER_MAJOR;
52 version->version_minor = DRIVER_MINOR;
53 version->version_patchlevel = DRIVER_PATCHLEVEL;
54 DRM_COPY( version->name, DRIVER_NAME );
55 DRM_COPY( version->date, DRIVER_DATE );
56 DRM_COPY( version->desc, DRIVER_DESC );
57 return 0;
58}
59
60static struct pci_device_id pciidlist[] = {
61 savage_PCI_IDS
62};
63
64extern drm_ioctl_desc_t savage_ioctls[];
65extern int savage_max_ioctl;
66
67static struct drm_driver driver = {
68 .driver_features =
69 DRIVER_USE_AGP | DRIVER_USE_MTRR |
70 DRIVER_HAVE_DMA | DRIVER_PCI_DMA,
71 .dev_priv_size = sizeof(drm_savage_buf_priv_t),
72 .preinit = savage_preinit,
73 .postinit = postinit,
74 .postcleanup = savage_postcleanup,
75 .reclaim_buffers = savage_reclaim_buffers,
76 .get_map_ofs = drm_core_get_map_ofs,
77 .get_reg_ofs = drm_core_get_reg_ofs,
78 .version = version,
79 .ioctls = savage_ioctls,
80 .dma_ioctl = savage_bci_buffers,
81 .fops = {
82 .owner = THIS_MODULE,
83 .open = drm_open,
84 .release = drm_release,
85 .ioctl = drm_ioctl,
86 .mmap = drm_mmap,
87 .poll = drm_poll,
88 .fasync = drm_fasync,
89 },
90 .pci_driver = {
91 .name = DRIVER_NAME,
92 .id_table = pciidlist,
93 }
94};
95
96static int __init savage_init(void)
97{
98 driver.num_ioctls = savage_max_ioctl;
99 return drm_init(&driver);
100}
101
102static void __exit savage_exit(void)
103{
104 drm_exit(&driver);
105}
106
107module_init(savage_init);
108module_exit(savage_exit);
109
110MODULE_AUTHOR( DRIVER_AUTHOR );
111MODULE_DESCRIPTION( DRIVER_DESC );
112MODULE_LICENSE("GPL and additional rights");
diff --git a/drivers/char/drm/savage_drv.h b/drivers/char/drm/savage_drv.h
new file mode 100644
index 000000000000..a45434944658
--- /dev/null
+++ b/drivers/char/drm/savage_drv.h
@@ -0,0 +1,579 @@
1/* savage_drv.h -- Private header for the savage driver
2 *
3 * Copyright 2004 Felix Kuehling
4 * All Rights Reserved.
5 *
6 * Permission is hereby granted, free of charge, to any person obtaining a
7 * copy of this software and associated documentation files (the "Software"),
8 * to deal in the Software without restriction, including without limitation
9 * the rights to use, copy, modify, merge, publish, distribute, sub license,
10 * and/or sell copies of the Software, and to permit persons to whom the
11 * Software is furnished to do so, subject to the following conditions:
12 *
13 * The above copyright notice and this permission notice (including the
14 * next paragraph) shall be included in all copies or substantial portions
15 * of the Software.
16 *
17 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
18 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
19 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
20 * NON-INFRINGEMENT. IN NO EVENT SHALL FELIX KUEHLING BE LIABLE FOR
21 * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF
22 * CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
23 * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
24 */
25
26#ifndef __SAVAGE_DRV_H__
27#define __SAVAGE_DRV_H__
28
29#define DRIVER_AUTHOR "Felix Kuehling"
30
31#define DRIVER_NAME "savage"
32#define DRIVER_DESC "Savage3D/MX/IX, Savage4, SuperSavage, Twister, ProSavage[DDR]"
33#define DRIVER_DATE "20050313"
34
35#define DRIVER_MAJOR 2
36#define DRIVER_MINOR 4
37#define DRIVER_PATCHLEVEL 1
38/* Interface history:
39 *
40 * 1.x The DRM driver from the VIA/S3 code drop, basically a dummy
41 * 2.0 The first real DRM
42 * 2.1 Scissors registers managed by the DRM, 3D operations clipped by
43 * cliprects of the cmdbuf ioctl
44 * 2.2 Implemented SAVAGE_CMD_DMA_IDX and SAVAGE_CMD_VB_IDX
45 * 2.3 Event counters used by BCI_EVENT_EMIT/WAIT ioctls are now 32 bits
46 * wide and thus very long lived (unlikely to ever wrap). The size
47 * in the struct was 32 bits before, but only 16 bits were used
48 * 2.4 Implemented command DMA. Now drm_savage_init_t.cmd_dma_offset is
49 * actually used
50 */
51
52typedef struct drm_savage_age {
53 uint16_t event;
54 unsigned int wrap;
55} drm_savage_age_t;
56
57typedef struct drm_savage_buf_priv {
58 struct drm_savage_buf_priv *next;
59 struct drm_savage_buf_priv *prev;
60 drm_savage_age_t age;
61 drm_buf_t *buf;
62} drm_savage_buf_priv_t;
63
64typedef struct drm_savage_dma_page {
65 drm_savage_age_t age;
66 unsigned int used, flushed;
67} drm_savage_dma_page_t;
68#define SAVAGE_DMA_PAGE_SIZE 1024 /* in dwords */
69/* Fake DMA buffer size in bytes. 4 pages. Allows a maximum command
70 * size of 16kbytes or 4k entries. Minimum requirement would be
71 * 10kbytes for 255 40-byte vertices in one drawing command. */
72#define SAVAGE_FAKE_DMA_SIZE (SAVAGE_DMA_PAGE_SIZE*4*4)
73
74/* interesting bits of hardware state that are saved in dev_priv */
75typedef union {
76 struct drm_savage_common_state {
77 uint32_t vbaddr;
78 } common;
79 struct {
80 unsigned char pad[sizeof(struct drm_savage_common_state)];
81 uint32_t texctrl, texaddr;
82 uint32_t scstart, new_scstart;
83 uint32_t scend, new_scend;
84 } s3d;
85 struct {
86 unsigned char pad[sizeof(struct drm_savage_common_state)];
87 uint32_t texdescr, texaddr0, texaddr1;
88 uint32_t drawctrl0, new_drawctrl0;
89 uint32_t drawctrl1, new_drawctrl1;
90 } s4;
91} drm_savage_state_t;
92
93/* these chip tags should match the ones in the 2D driver in savage_regs.h. */
94enum savage_family {
95 S3_UNKNOWN = 0,
96 S3_SAVAGE3D,
97 S3_SAVAGE_MX,
98 S3_SAVAGE4,
99 S3_PROSAVAGE,
100 S3_TWISTER,
101 S3_PROSAVAGEDDR,
102 S3_SUPERSAVAGE,
103 S3_SAVAGE2000,
104 S3_LAST
105};
106
107#define S3_SAVAGE3D_SERIES(chip) ((chip>=S3_SAVAGE3D) && (chip<=S3_SAVAGE_MX))
108
109#define S3_SAVAGE4_SERIES(chip) ((chip==S3_SAVAGE4) \
110 || (chip==S3_PROSAVAGE) \
111 || (chip==S3_TWISTER) \
112 || (chip==S3_PROSAVAGEDDR))
113
114#define S3_SAVAGE_MOBILE_SERIES(chip) ((chip==S3_SAVAGE_MX) || (chip==S3_SUPERSAVAGE))
115
116#define S3_SAVAGE_SERIES(chip) ((chip>=S3_SAVAGE3D) && (chip<=S3_SAVAGE2000))
117
118#define S3_MOBILE_TWISTER_SERIES(chip) ((chip==S3_TWISTER) \
119 ||(chip==S3_PROSAVAGEDDR))
120
121/* flags */
122#define SAVAGE_IS_AGP 1
123
124typedef struct drm_savage_private {
125 drm_savage_sarea_t *sarea_priv;
126
127 drm_savage_buf_priv_t head, tail;
128
129 /* who am I? */
130 enum savage_family chipset;
131
132 unsigned int cob_size;
133 unsigned int bci_threshold_lo, bci_threshold_hi;
134 unsigned int dma_type;
135
136 /* frame buffer layout */
137 unsigned int fb_bpp;
138 unsigned int front_offset, front_pitch;
139 unsigned int back_offset, back_pitch;
140 unsigned int depth_bpp;
141 unsigned int depth_offset, depth_pitch;
142
143 /* bitmap descriptors for swap and clear */
144 unsigned int front_bd, back_bd, depth_bd;
145
146 /* local textures */
147 unsigned int texture_offset;
148 unsigned int texture_size;
149
150 /* memory regions in physical memory */
151 drm_local_map_t *sarea;
152 drm_local_map_t *mmio;
153 drm_local_map_t *fb;
154 drm_local_map_t *aperture;
155 drm_local_map_t *status;
156 drm_local_map_t *agp_textures;
157 drm_local_map_t *cmd_dma;
158 drm_local_map_t fake_dma;
159
160 struct {
161 int handle;
162 unsigned long base, size;
163 } mtrr[3];
164
165 /* BCI and status-related stuff */
166 volatile uint32_t *status_ptr, *bci_ptr;
167 uint32_t status_used_mask;
168 uint16_t event_counter;
169 unsigned int event_wrap;
170
171 /* Savage4 command DMA */
172 drm_savage_dma_page_t *dma_pages;
173 unsigned int nr_dma_pages, first_dma_page, current_dma_page;
174 drm_savage_age_t last_dma_age;
175
176 /* saved hw state for global/local check on S3D */
177 uint32_t hw_draw_ctrl, hw_zbuf_ctrl;
178 /* and for scissors (global, so don't emit if not changed) */
179 uint32_t hw_scissors_start, hw_scissors_end;
180
181 drm_savage_state_t state;
182
183 /* after emitting a wait cmd Savage3D needs 63 nops before next DMA */
184 unsigned int waiting;
185
186 /* config/hardware-dependent function pointers */
187 int (*wait_fifo)(struct drm_savage_private *dev_priv, unsigned int n);
188 int (*wait_evnt)(struct drm_savage_private *dev_priv, uint16_t e);
189 /* Err, there is a macro wait_event in include/linux/wait.h.
190 * Avoid unwanted macro expansion. */
191 void (*emit_clip_rect)(struct drm_savage_private *dev_priv,
192 drm_clip_rect_t *pbox);
193 void (*dma_flush)(struct drm_savage_private *dev_priv);
194} drm_savage_private_t;
195
196/* ioctls */
197extern int savage_bci_cmdbuf(DRM_IOCTL_ARGS);
198extern int savage_bci_buffers(DRM_IOCTL_ARGS);
199
200/* BCI functions */
201extern uint16_t savage_bci_emit_event(drm_savage_private_t *dev_priv,
202 unsigned int flags);
203extern void savage_freelist_put(drm_device_t *dev, drm_buf_t *buf);
204extern void savage_dma_reset(drm_savage_private_t *dev_priv);
205extern void savage_dma_wait(drm_savage_private_t *dev_priv, unsigned int page);
206extern uint32_t *savage_dma_alloc(drm_savage_private_t *dev_priv,
207 unsigned int n);
208extern int savage_preinit(drm_device_t *dev, unsigned long chipset);
209extern int savage_postcleanup(drm_device_t *dev);
210extern int savage_do_cleanup_bci(drm_device_t *dev);
211extern void savage_reclaim_buffers(drm_device_t *dev, DRMFILE filp);
212
213/* state functions */
214extern void savage_emit_clip_rect_s3d(drm_savage_private_t *dev_priv,
215 drm_clip_rect_t *pbox);
216extern void savage_emit_clip_rect_s4(drm_savage_private_t *dev_priv,
217 drm_clip_rect_t *pbox);
218
219#define SAVAGE_FB_SIZE_S3 0x01000000 /* 16MB */
220#define SAVAGE_FB_SIZE_S4 0x02000000 /* 32MB */
221#define SAVAGE_MMIO_SIZE 0x00080000 /* 512kB */
222#define SAVAGE_APERTURE_OFFSET 0x02000000 /* 32MB */
223#define SAVAGE_APERTURE_SIZE 0x05000000 /* 5 tiled surfaces, 16MB each */
224
225#define SAVAGE_BCI_OFFSET 0x00010000 /* offset of the BCI region
226 * inside the MMIO region */
227#define SAVAGE_BCI_FIFO_SIZE 32 /* number of entries in on-chip
228 * BCI FIFO */
229
230/*
231 * MMIO registers
232 */
233#define SAVAGE_STATUS_WORD0 0x48C00
234#define SAVAGE_STATUS_WORD1 0x48C04
235#define SAVAGE_ALT_STATUS_WORD0 0x48C60
236
237#define SAVAGE_FIFO_USED_MASK_S3D 0x0001ffff
238#define SAVAGE_FIFO_USED_MASK_S4 0x001fffff
239
240/* Copied from savage_bci.h in the 2D driver with some renaming. */
241
242/* Bitmap descriptors */
243#define SAVAGE_BD_STRIDE_SHIFT 0
244#define SAVAGE_BD_BPP_SHIFT 16
245#define SAVAGE_BD_TILE_SHIFT 24
246#define SAVAGE_BD_BW_DISABLE (1<<28)
247/* common: */
248#define SAVAGE_BD_TILE_LINEAR 0
249/* savage4, MX, IX, 3D */
250#define SAVAGE_BD_TILE_16BPP 2
251#define SAVAGE_BD_TILE_32BPP 3
252/* twister, prosavage, DDR, supersavage, 2000 */
253#define SAVAGE_BD_TILE_DEST 1
254#define SAVAGE_BD_TILE_TEXTURE 2
255/* GBD - BCI enable */
256/* savage4, MX, IX, 3D */
257#define SAVAGE_GBD_BCI_ENABLE 8
258/* twister, prosavage, DDR, supersavage, 2000 */
259#define SAVAGE_GBD_BCI_ENABLE_TWISTER 0
260
261#define SAVAGE_GBD_BIG_ENDIAN 4
262#define SAVAGE_GBD_LITTLE_ENDIAN 0
263#define SAVAGE_GBD_64 1
264
265/* Global Bitmap Descriptor */
266#define SAVAGE_BCI_GLB_BD_LOW 0x8168
267#define SAVAGE_BCI_GLB_BD_HIGH 0x816C
268
269/*
270 * BCI registers
271 */
272/* Savage4/Twister/ProSavage 3D registers */
273#define SAVAGE_DRAWLOCALCTRL_S4 0x1e
274#define SAVAGE_TEXPALADDR_S4 0x1f
275#define SAVAGE_TEXCTRL0_S4 0x20
276#define SAVAGE_TEXCTRL1_S4 0x21
277#define SAVAGE_TEXADDR0_S4 0x22
278#define SAVAGE_TEXADDR1_S4 0x23
279#define SAVAGE_TEXBLEND0_S4 0x24
280#define SAVAGE_TEXBLEND1_S4 0x25
281#define SAVAGE_TEXXPRCLR_S4 0x26 /* never used */
282#define SAVAGE_TEXDESCR_S4 0x27
283#define SAVAGE_FOGTABLE_S4 0x28
284#define SAVAGE_FOGCTRL_S4 0x30
285#define SAVAGE_STENCILCTRL_S4 0x31
286#define SAVAGE_ZBUFCTRL_S4 0x32
287#define SAVAGE_ZBUFOFF_S4 0x33
288#define SAVAGE_DESTCTRL_S4 0x34
289#define SAVAGE_DRAWCTRL0_S4 0x35
290#define SAVAGE_DRAWCTRL1_S4 0x36
291#define SAVAGE_ZWATERMARK_S4 0x37
292#define SAVAGE_DESTTEXRWWATERMARK_S4 0x38
293#define SAVAGE_TEXBLENDCOLOR_S4 0x39
294/* Savage3D/MX/IX 3D registers */
295#define SAVAGE_TEXPALADDR_S3D 0x18
296#define SAVAGE_TEXXPRCLR_S3D 0x19 /* never used */
297#define SAVAGE_TEXADDR_S3D 0x1A
298#define SAVAGE_TEXDESCR_S3D 0x1B
299#define SAVAGE_TEXCTRL_S3D 0x1C
300#define SAVAGE_FOGTABLE_S3D 0x20
301#define SAVAGE_FOGCTRL_S3D 0x30
302#define SAVAGE_DRAWCTRL_S3D 0x31
303#define SAVAGE_ZBUFCTRL_S3D 0x32
304#define SAVAGE_ZBUFOFF_S3D 0x33
305#define SAVAGE_DESTCTRL_S3D 0x34
306#define SAVAGE_SCSTART_S3D 0x35
307#define SAVAGE_SCEND_S3D 0x36
308#define SAVAGE_ZWATERMARK_S3D 0x37
309#define SAVAGE_DESTTEXRWWATERMARK_S3D 0x38
310/* common stuff */
311#define SAVAGE_VERTBUFADDR 0x3e
312#define SAVAGE_BITPLANEWTMASK 0xd7
313#define SAVAGE_DMABUFADDR 0x51
314
315/* texture enable bits (needed for tex addr checking) */
316#define SAVAGE_TEXCTRL_TEXEN_MASK 0x00010000 /* S3D */
317#define SAVAGE_TEXDESCR_TEX0EN_MASK 0x02000000 /* S4 */
318#define SAVAGE_TEXDESCR_TEX1EN_MASK 0x04000000 /* S4 */
319
320/* Global fields in Savage4/Twister/ProSavage 3D registers:
321 *
322 * All texture registers and DrawLocalCtrl are local. All other
323 * registers are global. */
324
325/* Global fields in Savage3D/MX/IX 3D registers:
326 *
327 * All texture registers are local. DrawCtrl and ZBufCtrl are
328 * partially local. All other registers are global.
329 *
330 * DrawCtrl global fields: cullMode, alphaTestCmpFunc, alphaTestEn, alphaRefVal
331 * ZBufCtrl global fields: zCmpFunc, zBufEn
332 */
333#define SAVAGE_DRAWCTRL_S3D_GLOBAL 0x03f3c00c
334#define SAVAGE_ZBUFCTRL_S3D_GLOBAL 0x00000027
335
336/* Masks for scissor bits (drawCtrl[01] on s4, scissorStart/End on s3d)
337 */
338#define SAVAGE_SCISSOR_MASK_S4 0x00fff7ff
339#define SAVAGE_SCISSOR_MASK_S3D 0x07ff07ff
340
341/*
342 * BCI commands
343 */
344#define BCI_CMD_NOP 0x40000000
345#define BCI_CMD_RECT 0x48000000
346#define BCI_CMD_RECT_XP 0x01000000
347#define BCI_CMD_RECT_YP 0x02000000
348#define BCI_CMD_SCANLINE 0x50000000
349#define BCI_CMD_LINE 0x5C000000
350#define BCI_CMD_LINE_LAST_PIXEL 0x58000000
351#define BCI_CMD_BYTE_TEXT 0x63000000
352#define BCI_CMD_NT_BYTE_TEXT 0x67000000
353#define BCI_CMD_BIT_TEXT 0x6C000000
354#define BCI_CMD_GET_ROP(cmd) (((cmd) >> 16) & 0xFF)
355#define BCI_CMD_SET_ROP(cmd, rop) ((cmd) |= ((rop & 0xFF) << 16))
356#define BCI_CMD_SEND_COLOR 0x00008000
357
358#define BCI_CMD_CLIP_NONE 0x00000000
359#define BCI_CMD_CLIP_CURRENT 0x00002000
360#define BCI_CMD_CLIP_LR 0x00004000
361#define BCI_CMD_CLIP_NEW 0x00006000
362
363#define BCI_CMD_DEST_GBD 0x00000000
364#define BCI_CMD_DEST_PBD 0x00000800
365#define BCI_CMD_DEST_PBD_NEW 0x00000C00
366#define BCI_CMD_DEST_SBD 0x00001000
367#define BCI_CMD_DEST_SBD_NEW 0x00001400
368
369#define BCI_CMD_SRC_TRANSPARENT 0x00000200
370#define BCI_CMD_SRC_SOLID 0x00000000
371#define BCI_CMD_SRC_GBD 0x00000020
372#define BCI_CMD_SRC_COLOR 0x00000040
373#define BCI_CMD_SRC_MONO 0x00000060
374#define BCI_CMD_SRC_PBD_COLOR 0x00000080
375#define BCI_CMD_SRC_PBD_MONO 0x000000A0
376#define BCI_CMD_SRC_PBD_COLOR_NEW 0x000000C0
377#define BCI_CMD_SRC_PBD_MONO_NEW 0x000000E0
378#define BCI_CMD_SRC_SBD_COLOR 0x00000100
379#define BCI_CMD_SRC_SBD_MONO 0x00000120
380#define BCI_CMD_SRC_SBD_COLOR_NEW 0x00000140
381#define BCI_CMD_SRC_SBD_MONO_NEW 0x00000160
382
383#define BCI_CMD_PAT_TRANSPARENT 0x00000010
384#define BCI_CMD_PAT_NONE 0x00000000
385#define BCI_CMD_PAT_COLOR 0x00000002
386#define BCI_CMD_PAT_MONO 0x00000003
387#define BCI_CMD_PAT_PBD_COLOR 0x00000004
388#define BCI_CMD_PAT_PBD_MONO 0x00000005
389#define BCI_CMD_PAT_PBD_COLOR_NEW 0x00000006
390#define BCI_CMD_PAT_PBD_MONO_NEW 0x00000007
391#define BCI_CMD_PAT_SBD_COLOR 0x00000008
392#define BCI_CMD_PAT_SBD_MONO 0x00000009
393#define BCI_CMD_PAT_SBD_COLOR_NEW 0x0000000A
394#define BCI_CMD_PAT_SBD_MONO_NEW 0x0000000B
395
396#define BCI_BD_BW_DISABLE 0x10000000
397#define BCI_BD_TILE_MASK 0x03000000
398#define BCI_BD_TILE_NONE 0x00000000
399#define BCI_BD_TILE_16 0x02000000
400#define BCI_BD_TILE_32 0x03000000
401#define BCI_BD_GET_BPP(bd) (((bd) >> 16) & 0xFF)
402#define BCI_BD_SET_BPP(bd, bpp) ((bd) |= (((bpp) & 0xFF) << 16))
403#define BCI_BD_GET_STRIDE(bd) ((bd) & 0xFFFF)
404#define BCI_BD_SET_STRIDE(bd, st) ((bd) |= ((st) & 0xFFFF))
405
406#define BCI_CMD_SET_REGISTER 0x96000000
407
408#define BCI_CMD_WAIT 0xC0000000
409#define BCI_CMD_WAIT_3D 0x00010000
410#define BCI_CMD_WAIT_2D 0x00020000
411
412#define BCI_CMD_UPDATE_EVENT_TAG 0x98000000
413
414#define BCI_CMD_DRAW_PRIM 0x80000000
415#define BCI_CMD_DRAW_INDEXED_PRIM 0x88000000
416#define BCI_CMD_DRAW_CONT 0x01000000
417#define BCI_CMD_DRAW_TRILIST 0x00000000
418#define BCI_CMD_DRAW_TRISTRIP 0x02000000
419#define BCI_CMD_DRAW_TRIFAN 0x04000000
420#define BCI_CMD_DRAW_SKIPFLAGS 0x000000ff
421#define BCI_CMD_DRAW_NO_Z 0x00000001
422#define BCI_CMD_DRAW_NO_W 0x00000002
423#define BCI_CMD_DRAW_NO_CD 0x00000004
424#define BCI_CMD_DRAW_NO_CS 0x00000008
425#define BCI_CMD_DRAW_NO_U0 0x00000010
426#define BCI_CMD_DRAW_NO_V0 0x00000020
427#define BCI_CMD_DRAW_NO_UV0 0x00000030
428#define BCI_CMD_DRAW_NO_U1 0x00000040
429#define BCI_CMD_DRAW_NO_V1 0x00000080
430#define BCI_CMD_DRAW_NO_UV1 0x000000c0
431
432#define BCI_CMD_DMA 0xa8000000
433
434#define BCI_W_H(w, h) ((((h) << 16) | (w)) & 0x0FFF0FFF)
435#define BCI_X_Y(x, y) ((((y) << 16) | (x)) & 0x0FFF0FFF)
436#define BCI_X_W(x, y) ((((w) << 16) | (x)) & 0x0FFF0FFF)
437#define BCI_CLIP_LR(l, r) ((((r) << 16) | (l)) & 0x0FFF0FFF)
438#define BCI_CLIP_TL(t, l) ((((t) << 16) | (l)) & 0x0FFF0FFF)
439#define BCI_CLIP_BR(b, r) ((((b) << 16) | (r)) & 0x0FFF0FFF)
440
441#define BCI_LINE_X_Y(x, y) (((y) << 16) | ((x) & 0xFFFF))
442#define BCI_LINE_STEPS(diag, axi) (((axi) << 16) | ((diag) & 0xFFFF))
443#define BCI_LINE_MISC(maj, ym, xp, yp, err) \
444 (((maj) & 0x1FFF) | \
445 ((ym) ? 1<<13 : 0) | \
446 ((xp) ? 1<<14 : 0) | \
447 ((yp) ? 1<<15 : 0) | \
448 ((err) << 16))
449
450/*
451 * common commands
452 */
453#define BCI_SET_REGISTERS( first, n ) \
454 BCI_WRITE(BCI_CMD_SET_REGISTER | \
455 ((uint32_t)(n) & 0xff) << 16 | \
456 ((uint32_t)(first) & 0xffff))
457#define DMA_SET_REGISTERS( first, n ) \
458 DMA_WRITE(BCI_CMD_SET_REGISTER | \
459 ((uint32_t)(n) & 0xff) << 16 | \
460 ((uint32_t)(first) & 0xffff))
461
462#define BCI_DRAW_PRIMITIVE(n, type, skip) \
463 BCI_WRITE(BCI_CMD_DRAW_PRIM | (type) | (skip) | \
464 ((n) << 16))
465#define DMA_DRAW_PRIMITIVE(n, type, skip) \
466 DMA_WRITE(BCI_CMD_DRAW_PRIM | (type) | (skip) | \
467 ((n) << 16))
468
469#define BCI_DRAW_INDICES_S3D(n, type, i0) \
470 BCI_WRITE(BCI_CMD_DRAW_INDEXED_PRIM | (type) | \
471 ((n) << 16) | (i0))
472
473#define BCI_DRAW_INDICES_S4(n, type, skip) \
474 BCI_WRITE(BCI_CMD_DRAW_INDEXED_PRIM | (type) | \
475 (skip) | ((n) << 16))
476
477#define BCI_DMA(n) \
478 BCI_WRITE(BCI_CMD_DMA | (((n) >> 1) - 1))
479
480/*
481 * access to MMIO
482 */
483#define SAVAGE_READ(reg) DRM_READ32( dev_priv->mmio, (reg) )
484#define SAVAGE_WRITE(reg) DRM_WRITE32( dev_priv->mmio, (reg) )
485
486/*
487 * access to the burst command interface (BCI)
488 */
489#define SAVAGE_BCI_DEBUG 1
490
491#define BCI_LOCALS volatile uint32_t *bci_ptr;
492
493#define BEGIN_BCI( n ) do { \
494 dev_priv->wait_fifo(dev_priv, (n)); \
495 bci_ptr = dev_priv->bci_ptr; \
496} while(0)
497
498#define BCI_WRITE( val ) *bci_ptr++ = (uint32_t)(val)
499
500#define BCI_COPY_FROM_USER(src,n) do { \
501 unsigned int i; \
502 for (i = 0; i < n; ++i) { \
503 uint32_t val; \
504 DRM_GET_USER_UNCHECKED(val, &((uint32_t*)(src))[i]); \
505 BCI_WRITE(val); \
506 } \
507} while(0)
508
509/*
510 * command DMA support
511 */
512#define SAVAGE_DMA_DEBUG 1
513
514#define DMA_LOCALS uint32_t *dma_ptr;
515
516#define BEGIN_DMA( n ) do { \
517 unsigned int cur = dev_priv->current_dma_page; \
518 unsigned int rest = SAVAGE_DMA_PAGE_SIZE - \
519 dev_priv->dma_pages[cur].used; \
520 if ((n) > rest) { \
521 dma_ptr = savage_dma_alloc(dev_priv, (n)); \
522 } else { /* fast path for small allocations */ \
523 dma_ptr = (uint32_t *)dev_priv->cmd_dma->handle + \
524 cur * SAVAGE_DMA_PAGE_SIZE + \
525 dev_priv->dma_pages[cur].used; \
526 if (dev_priv->dma_pages[cur].used == 0) \
527 savage_dma_wait(dev_priv, cur); \
528 dev_priv->dma_pages[cur].used += (n); \
529 } \
530} while(0)
531
532#define DMA_WRITE( val ) *dma_ptr++ = (uint32_t)(val)
533
534#define DMA_COPY_FROM_USER(src,n) do { \
535 DRM_COPY_FROM_USER_UNCHECKED(dma_ptr, (src), (n)*4); \
536 dma_ptr += n; \
537} while(0)
538
539#if SAVAGE_DMA_DEBUG
540#define DMA_COMMIT() do { \
541 unsigned int cur = dev_priv->current_dma_page; \
542 uint32_t *expected = (uint32_t *)dev_priv->cmd_dma->handle + \
543 cur * SAVAGE_DMA_PAGE_SIZE + \
544 dev_priv->dma_pages[cur].used; \
545 if (dma_ptr != expected) { \
546 DRM_ERROR("DMA allocation and use don't match: " \
547 "%p != %p\n", expected, dma_ptr); \
548 savage_dma_reset(dev_priv); \
549 } \
550} while(0)
551#else
552#define DMA_COMMIT() do {/* nothing */} while(0)
553#endif
554
555#define DMA_FLUSH() dev_priv->dma_flush(dev_priv)
556
557/* Buffer aging via event tag
558 */
559
560#define UPDATE_EVENT_COUNTER( ) do { \
561 if (dev_priv->status_ptr) { \
562 uint16_t count; \
563 /* coordinate with Xserver */ \
564 count = dev_priv->status_ptr[1023]; \
565 if (count < dev_priv->event_counter) \
566 dev_priv->event_wrap++; \
567 dev_priv->event_counter = count; \
568 } \
569} while(0)
570
571#define SET_AGE( age, e, w ) do { \
572 (age)->event = e; \
573 (age)->wrap = w; \
574} while(0)
575
576#define TEST_AGE( age, e, w ) \
577 ( (age)->wrap < (w) || ( (age)->wrap == (w) && (age)->event <= (e) ) )
578
579#endif /* __SAVAGE_DRV_H__ */
diff --git a/drivers/char/drm/savage_state.c b/drivers/char/drm/savage_state.c
new file mode 100644
index 000000000000..475695a00083
--- /dev/null
+++ b/drivers/char/drm/savage_state.c
@@ -0,0 +1,1146 @@
1/* savage_state.c -- State and drawing support for Savage
2 *
3 * Copyright 2004 Felix Kuehling
4 * All Rights Reserved.
5 *
6 * Permission is hereby granted, free of charge, to any person obtaining a
7 * copy of this software and associated documentation files (the "Software"),
8 * to deal in the Software without restriction, including without limitation
9 * the rights to use, copy, modify, merge, publish, distribute, sub license,
10 * and/or sell copies of the Software, and to permit persons to whom the
11 * Software is furnished to do so, subject to the following conditions:
12 *
13 * The above copyright notice and this permission notice (including the
14 * next paragraph) shall be included in all copies or substantial portions
15 * of the Software.
16 *
17 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
18 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
19 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
20 * NON-INFRINGEMENT. IN NO EVENT SHALL FELIX KUEHLING BE LIABLE FOR
21 * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF
22 * CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
23 * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
24 */
25#include "drmP.h"
26#include "savage_drm.h"
27#include "savage_drv.h"
28
29void savage_emit_clip_rect_s3d(drm_savage_private_t *dev_priv,
30 drm_clip_rect_t *pbox)
31{
32 uint32_t scstart = dev_priv->state.s3d.new_scstart;
33 uint32_t scend = dev_priv->state.s3d.new_scend;
34 scstart = (scstart & ~SAVAGE_SCISSOR_MASK_S3D) |
35 ((uint32_t)pbox->x1 & 0x000007ff) |
36 (((uint32_t)pbox->y1 << 16) & 0x07ff0000);
37 scend = (scend & ~SAVAGE_SCISSOR_MASK_S3D) |
38 (((uint32_t)pbox->x2-1) & 0x000007ff) |
39 ((((uint32_t)pbox->y2-1) << 16) & 0x07ff0000);
40 if (scstart != dev_priv->state.s3d.scstart ||
41 scend != dev_priv->state.s3d.scend) {
42 DMA_LOCALS;
43 BEGIN_DMA(4);
44 DMA_WRITE(BCI_CMD_WAIT|BCI_CMD_WAIT_3D);
45 DMA_SET_REGISTERS(SAVAGE_SCSTART_S3D, 2);
46 DMA_WRITE(scstart);
47 DMA_WRITE(scend);
48 dev_priv->state.s3d.scstart = scstart;
49 dev_priv->state.s3d.scend = scend;
50 dev_priv->waiting = 1;
51 DMA_COMMIT();
52 }
53}
54
55void savage_emit_clip_rect_s4(drm_savage_private_t *dev_priv,
56 drm_clip_rect_t *pbox)
57{
58 uint32_t drawctrl0 = dev_priv->state.s4.new_drawctrl0;
59 uint32_t drawctrl1 = dev_priv->state.s4.new_drawctrl1;
60 drawctrl0 = (drawctrl0 & ~SAVAGE_SCISSOR_MASK_S4) |
61 ((uint32_t)pbox->x1 & 0x000007ff) |
62 (((uint32_t)pbox->y1 << 12) & 0x00fff000);
63 drawctrl1 = (drawctrl1 & ~SAVAGE_SCISSOR_MASK_S4) |
64 (((uint32_t)pbox->x2-1) & 0x000007ff) |
65 ((((uint32_t)pbox->y2-1) << 12) & 0x00fff000);
66 if (drawctrl0 != dev_priv->state.s4.drawctrl0 ||
67 drawctrl1 != dev_priv->state.s4.drawctrl1) {
68 DMA_LOCALS;
69 BEGIN_DMA(4);
70 DMA_WRITE(BCI_CMD_WAIT|BCI_CMD_WAIT_3D);
71 DMA_SET_REGISTERS(SAVAGE_DRAWCTRL0_S4, 2);
72 DMA_WRITE(drawctrl0);
73 DMA_WRITE(drawctrl1);
74 dev_priv->state.s4.drawctrl0 = drawctrl0;
75 dev_priv->state.s4.drawctrl1 = drawctrl1;
76 dev_priv->waiting = 1;
77 DMA_COMMIT();
78 }
79}
80
81static int savage_verify_texaddr(drm_savage_private_t *dev_priv, int unit,
82 uint32_t addr)
83{
84 if ((addr & 6) != 2) { /* reserved bits */
85 DRM_ERROR("bad texAddr%d %08x (reserved bits)\n", unit, addr);
86 return DRM_ERR(EINVAL);
87 }
88 if (!(addr & 1)) { /* local */
89 addr &= ~7;
90 if (addr < dev_priv->texture_offset ||
91 addr >= dev_priv->texture_offset+dev_priv->texture_size) {
92 DRM_ERROR("bad texAddr%d %08x (local addr out of range)\n",
93 unit, addr);
94 return DRM_ERR(EINVAL);
95 }
96 } else { /* AGP */
97 if (!dev_priv->agp_textures) {
98 DRM_ERROR("bad texAddr%d %08x (AGP not available)\n",
99 unit, addr);
100 return DRM_ERR(EINVAL);
101 }
102 addr &= ~7;
103 if (addr < dev_priv->agp_textures->offset ||
104 addr >= (dev_priv->agp_textures->offset +
105 dev_priv->agp_textures->size)) {
106 DRM_ERROR("bad texAddr%d %08x (AGP addr out of range)\n",
107 unit, addr);
108 return DRM_ERR(EINVAL);
109 }
110 }
111 return 0;
112}
113
114#define SAVE_STATE(reg,where) \
115 if(start <= reg && start+count > reg) \
116 DRM_GET_USER_UNCHECKED(dev_priv->state.where, &regs[reg-start])
117#define SAVE_STATE_MASK(reg,where,mask) do { \
118 if(start <= reg && start+count > reg) { \
119 uint32_t tmp; \
120 DRM_GET_USER_UNCHECKED(tmp, &regs[reg-start]); \
121 dev_priv->state.where = (tmp & (mask)) | \
122 (dev_priv->state.where & ~(mask)); \
123 } \
124} while (0)
125static int savage_verify_state_s3d(drm_savage_private_t *dev_priv,
126 unsigned int start, unsigned int count,
127 const uint32_t __user *regs)
128{
129 if (start < SAVAGE_TEXPALADDR_S3D ||
130 start+count-1 > SAVAGE_DESTTEXRWWATERMARK_S3D) {
131 DRM_ERROR("invalid register range (0x%04x-0x%04x)\n",
132 start, start+count-1);
133 return DRM_ERR(EINVAL);
134 }
135
136 SAVE_STATE_MASK(SAVAGE_SCSTART_S3D, s3d.new_scstart,
137 ~SAVAGE_SCISSOR_MASK_S3D);
138 SAVE_STATE_MASK(SAVAGE_SCEND_S3D, s3d.new_scend,
139 ~SAVAGE_SCISSOR_MASK_S3D);
140
141 /* if any texture regs were changed ... */
142 if (start <= SAVAGE_TEXCTRL_S3D &&
143 start+count > SAVAGE_TEXPALADDR_S3D) {
144 /* ... check texture state */
145 SAVE_STATE(SAVAGE_TEXCTRL_S3D, s3d.texctrl);
146 SAVE_STATE(SAVAGE_TEXADDR_S3D, s3d.texaddr);
147 if (dev_priv->state.s3d.texctrl & SAVAGE_TEXCTRL_TEXEN_MASK)
148 return savage_verify_texaddr(
149 dev_priv, 0, dev_priv->state.s3d.texaddr);
150 }
151
152 return 0;
153}
154
155static int savage_verify_state_s4(drm_savage_private_t *dev_priv,
156 unsigned int start, unsigned int count,
157 const uint32_t __user *regs)
158{
159 int ret = 0;
160
161 if (start < SAVAGE_DRAWLOCALCTRL_S4 ||
162 start+count-1 > SAVAGE_TEXBLENDCOLOR_S4) {
163 DRM_ERROR("invalid register range (0x%04x-0x%04x)\n",
164 start, start+count-1);
165 return DRM_ERR(EINVAL);
166 }
167
168 SAVE_STATE_MASK(SAVAGE_DRAWCTRL0_S4, s4.new_drawctrl0,
169 ~SAVAGE_SCISSOR_MASK_S4);
170 SAVE_STATE_MASK(SAVAGE_DRAWCTRL1_S4, s4.new_drawctrl1,
171 ~SAVAGE_SCISSOR_MASK_S4);
172
173 /* if any texture regs were changed ... */
174 if (start <= SAVAGE_TEXDESCR_S4 &&
175 start+count > SAVAGE_TEXPALADDR_S4) {
176 /* ... check texture state */
177 SAVE_STATE(SAVAGE_TEXDESCR_S4, s4.texdescr);
178 SAVE_STATE(SAVAGE_TEXADDR0_S4, s4.texaddr0);
179 SAVE_STATE(SAVAGE_TEXADDR1_S4, s4.texaddr1);
180 if (dev_priv->state.s4.texdescr & SAVAGE_TEXDESCR_TEX0EN_MASK)
181 ret |= savage_verify_texaddr(
182 dev_priv, 0, dev_priv->state.s4.texaddr0);
183 if (dev_priv->state.s4.texdescr & SAVAGE_TEXDESCR_TEX1EN_MASK)
184 ret |= savage_verify_texaddr(
185 dev_priv, 1, dev_priv->state.s4.texaddr1);
186 }
187
188 return ret;
189}
190#undef SAVE_STATE
191#undef SAVE_STATE_MASK
192
193static int savage_dispatch_state(drm_savage_private_t *dev_priv,
194 const drm_savage_cmd_header_t *cmd_header,
195 const uint32_t __user *regs)
196{
197 unsigned int count = cmd_header->state.count;
198 unsigned int start = cmd_header->state.start;
199 unsigned int count2 = 0;
200 unsigned int bci_size;
201 int ret;
202 DMA_LOCALS;
203
204 if (!count)
205 return 0;
206
207 if (DRM_VERIFYAREA_READ(regs, count*4))
208 return DRM_ERR(EFAULT);
209
210 if (S3_SAVAGE3D_SERIES(dev_priv->chipset)) {
211 ret = savage_verify_state_s3d(dev_priv, start, count, regs);
212 if (ret != 0)
213 return ret;
214 /* scissor regs are emitted in savage_dispatch_draw */
215 if (start < SAVAGE_SCSTART_S3D) {
216 if (start+count > SAVAGE_SCEND_S3D+1)
217 count2 = count - (SAVAGE_SCEND_S3D+1 - start);
218 if (start+count > SAVAGE_SCSTART_S3D)
219 count = SAVAGE_SCSTART_S3D - start;
220 } else if (start <= SAVAGE_SCEND_S3D) {
221 if (start+count > SAVAGE_SCEND_S3D+1) {
222 count -= SAVAGE_SCEND_S3D+1 - start;
223 start = SAVAGE_SCEND_S3D+1;
224 } else
225 return 0;
226 }
227 } else {
228 ret = savage_verify_state_s4(dev_priv, start, count, regs);
229 if (ret != 0)
230 return ret;
231 /* scissor regs are emitted in savage_dispatch_draw */
232 if (start < SAVAGE_DRAWCTRL0_S4) {
233 if (start+count > SAVAGE_DRAWCTRL1_S4+1)
234 count2 = count - (SAVAGE_DRAWCTRL1_S4+1 - start);
235 if (start+count > SAVAGE_DRAWCTRL0_S4)
236 count = SAVAGE_DRAWCTRL0_S4 - start;
237 } else if (start <= SAVAGE_DRAWCTRL1_S4) {
238 if (start+count > SAVAGE_DRAWCTRL1_S4+1) {
239 count -= SAVAGE_DRAWCTRL1_S4+1 - start;
240 start = SAVAGE_DRAWCTRL1_S4+1;
241 } else
242 return 0;
243 }
244 }
245
246 bci_size = count + (count+254)/255 + count2 + (count2+254)/255;
247
248 if (cmd_header->state.global) {
249 BEGIN_DMA(bci_size+1);
250 DMA_WRITE(BCI_CMD_WAIT | BCI_CMD_WAIT_3D);
251 dev_priv->waiting = 1;
252 } else {
253 BEGIN_DMA(bci_size);
254 }
255
256 do {
257 while (count > 0) {
258 unsigned int n = count < 255 ? count : 255;
259 DMA_SET_REGISTERS(start, n);
260 DMA_COPY_FROM_USER(regs, n);
261 count -= n;
262 start += n;
263 regs += n;
264 }
265 start += 2;
266 regs += 2;
267 count = count2;
268 count2 = 0;
269 } while (count);
270
271 DMA_COMMIT();
272
273 return 0;
274}
275
276static int savage_dispatch_dma_prim(drm_savage_private_t *dev_priv,
277 const drm_savage_cmd_header_t *cmd_header,
278 const drm_buf_t *dmabuf)
279{
280 unsigned char reorder = 0;
281 unsigned int prim = cmd_header->prim.prim;
282 unsigned int skip = cmd_header->prim.skip;
283 unsigned int n = cmd_header->prim.count;
284 unsigned int start = cmd_header->prim.start;
285 unsigned int i;
286 BCI_LOCALS;
287
288 if (!dmabuf) {
289 DRM_ERROR("called without dma buffers!\n");
290 return DRM_ERR(EINVAL);
291 }
292
293 if (!n)
294 return 0;
295
296 switch (prim) {
297 case SAVAGE_PRIM_TRILIST_201:
298 reorder = 1;
299 prim = SAVAGE_PRIM_TRILIST;
300 case SAVAGE_PRIM_TRILIST:
301 if (n % 3 != 0) {
302 DRM_ERROR("wrong number of vertices %u in TRILIST\n",
303 n);
304 return DRM_ERR(EINVAL);
305 }
306 break;
307 case SAVAGE_PRIM_TRISTRIP:
308 case SAVAGE_PRIM_TRIFAN:
309 if (n < 3) {
310 DRM_ERROR("wrong number of vertices %u in TRIFAN/STRIP\n",
311 n);
312 return DRM_ERR(EINVAL);
313 }
314 break;
315 default:
316 DRM_ERROR("invalid primitive type %u\n", prim);
317 return DRM_ERR(EINVAL);
318 }
319
320 if (S3_SAVAGE3D_SERIES(dev_priv->chipset)) {
321 if (skip != 0) {
322 DRM_ERROR("invalid skip flags 0x%04x for DMA\n",
323 skip);
324 return DRM_ERR(EINVAL);
325 }
326 } else {
327 unsigned int size = 10 - (skip & 1) - (skip >> 1 & 1) -
328 (skip >> 2 & 1) - (skip >> 3 & 1) - (skip >> 4 & 1) -
329 (skip >> 5 & 1) - (skip >> 6 & 1) - (skip >> 7 & 1);
330 if (skip > SAVAGE_SKIP_ALL_S4 || size != 8) {
331 DRM_ERROR("invalid skip flags 0x%04x for DMA\n",
332 skip);
333 return DRM_ERR(EINVAL);
334 }
335 if (reorder) {
336 DRM_ERROR("TRILIST_201 used on Savage4 hardware\n");
337 return DRM_ERR(EINVAL);
338 }
339 }
340
341 if (start + n > dmabuf->total/32) {
342 DRM_ERROR("vertex indices (%u-%u) out of range (0-%u)\n",
343 start, start + n - 1, dmabuf->total/32);
344 return DRM_ERR(EINVAL);
345 }
346
347 /* Vertex DMA doesn't work with command DMA at the same time,
348 * so we use BCI_... to submit commands here. Flush buffered
349 * faked DMA first. */
350 DMA_FLUSH();
351
352 if (dmabuf->bus_address != dev_priv->state.common.vbaddr) {
353 BEGIN_BCI(2);
354 BCI_SET_REGISTERS(SAVAGE_VERTBUFADDR, 1);
355 BCI_WRITE(dmabuf->bus_address | dev_priv->dma_type);
356 dev_priv->state.common.vbaddr = dmabuf->bus_address;
357 }
358 if (S3_SAVAGE3D_SERIES(dev_priv->chipset) && dev_priv->waiting) {
359 /* Workaround for what looks like a hardware bug. If a
360 * WAIT_3D_IDLE was emitted some time before the
361 * indexed drawing command then the engine will lock
362 * up. There are two known workarounds:
363 * WAIT_IDLE_EMPTY or emit at least 63 NOPs. */
364 BEGIN_BCI(63);
365 for (i = 0; i < 63; ++i)
366 BCI_WRITE(BCI_CMD_WAIT);
367 dev_priv->waiting = 0;
368 }
369
370 prim <<= 25;
371 while (n != 0) {
372 /* Can emit up to 255 indices (85 triangles) at once. */
373 unsigned int count = n > 255 ? 255 : n;
374 if (reorder) {
375 /* Need to reorder indices for correct flat
376 * shading while preserving the clock sense
377 * for correct culling. Only on Savage3D. */
378 int reorder[3] = {-1, -1, -1};
379 reorder[start%3] = 2;
380
381 BEGIN_BCI((count+1+1)/2);
382 BCI_DRAW_INDICES_S3D(count, prim, start+2);
383
384 for (i = start+1; i+1 < start+count; i += 2)
385 BCI_WRITE((i + reorder[i % 3]) |
386 ((i+1 + reorder[(i+1) % 3]) << 16));
387 if (i < start+count)
388 BCI_WRITE(i + reorder[i%3]);
389 } else if (S3_SAVAGE3D_SERIES(dev_priv->chipset)) {
390 BEGIN_BCI((count+1+1)/2);
391 BCI_DRAW_INDICES_S3D(count, prim, start);
392
393 for (i = start+1; i+1 < start+count; i += 2)
394 BCI_WRITE(i | ((i+1) << 16));
395 if (i < start+count)
396 BCI_WRITE(i);
397 } else {
398 BEGIN_BCI((count+2+1)/2);
399 BCI_DRAW_INDICES_S4(count, prim, skip);
400
401 for (i = start; i+1 < start+count; i += 2)
402 BCI_WRITE(i | ((i+1) << 16));
403 if (i < start+count)
404 BCI_WRITE(i);
405 }
406
407 start += count;
408 n -= count;
409
410 prim |= BCI_CMD_DRAW_CONT;
411 }
412
413 return 0;
414}
415
416static int savage_dispatch_vb_prim(drm_savage_private_t *dev_priv,
417 const drm_savage_cmd_header_t *cmd_header,
418 const uint32_t __user *vtxbuf,
419 unsigned int vb_size,
420 unsigned int vb_stride)
421{
422 unsigned char reorder = 0;
423 unsigned int prim = cmd_header->prim.prim;
424 unsigned int skip = cmd_header->prim.skip;
425 unsigned int n = cmd_header->prim.count;
426 unsigned int start = cmd_header->prim.start;
427 unsigned int vtx_size;
428 unsigned int i;
429 DMA_LOCALS;
430
431 if (!n)
432 return 0;
433
434 switch (prim) {
435 case SAVAGE_PRIM_TRILIST_201:
436 reorder = 1;
437 prim = SAVAGE_PRIM_TRILIST;
438 case SAVAGE_PRIM_TRILIST:
439 if (n % 3 != 0) {
440 DRM_ERROR("wrong number of vertices %u in TRILIST\n",
441 n);
442 return DRM_ERR(EINVAL);
443 }
444 break;
445 case SAVAGE_PRIM_TRISTRIP:
446 case SAVAGE_PRIM_TRIFAN:
447 if (n < 3) {
448 DRM_ERROR("wrong number of vertices %u in TRIFAN/STRIP\n",
449 n);
450 return DRM_ERR(EINVAL);
451 }
452 break;
453 default:
454 DRM_ERROR("invalid primitive type %u\n", prim);
455 return DRM_ERR(EINVAL);
456 }
457
458 if (S3_SAVAGE3D_SERIES(dev_priv->chipset)) {
459 if (skip > SAVAGE_SKIP_ALL_S3D) {
460 DRM_ERROR("invalid skip flags 0x%04x\n", skip);
461 return DRM_ERR(EINVAL);
462 }
463 vtx_size = 8; /* full vertex */
464 } else {
465 if (skip > SAVAGE_SKIP_ALL_S4) {
466 DRM_ERROR("invalid skip flags 0x%04x\n", skip);
467 return DRM_ERR(EINVAL);
468 }
469 vtx_size = 10; /* full vertex */
470 }
471
472 vtx_size -= (skip & 1) + (skip >> 1 & 1) +
473 (skip >> 2 & 1) + (skip >> 3 & 1) + (skip >> 4 & 1) +
474 (skip >> 5 & 1) + (skip >> 6 & 1) + (skip >> 7 & 1);
475
476 if (vtx_size > vb_stride) {
477 DRM_ERROR("vertex size greater than vb stride (%u > %u)\n",
478 vtx_size, vb_stride);
479 return DRM_ERR(EINVAL);
480 }
481
482 if (start + n > vb_size / (vb_stride*4)) {
483 DRM_ERROR("vertex indices (%u-%u) out of range (0-%u)\n",
484 start, start + n - 1, vb_size / (vb_stride*4));
485 return DRM_ERR(EINVAL);
486 }
487
488 prim <<= 25;
489 while (n != 0) {
490 /* Can emit up to 255 vertices (85 triangles) at once. */
491 unsigned int count = n > 255 ? 255 : n;
492 if (reorder) {
493 /* Need to reorder vertices for correct flat
494 * shading while preserving the clock sense
495 * for correct culling. Only on Savage3D. */
496 int reorder[3] = {-1, -1, -1};
497 reorder[start%3] = 2;
498
499 BEGIN_DMA(count*vtx_size+1);
500 DMA_DRAW_PRIMITIVE(count, prim, skip);
501
502 for (i = start; i < start+count; ++i) {
503 unsigned int j = i + reorder[i % 3];
504 DMA_COPY_FROM_USER(&vtxbuf[vb_stride*j],
505 vtx_size);
506 }
507
508 DMA_COMMIT();
509 } else {
510 BEGIN_DMA(count*vtx_size+1);
511 DMA_DRAW_PRIMITIVE(count, prim, skip);
512
513 if (vb_stride == vtx_size) {
514 DMA_COPY_FROM_USER(&vtxbuf[vb_stride*start],
515 vtx_size*count);
516 } else {
517 for (i = start; i < start+count; ++i) {
518 DMA_COPY_FROM_USER(
519 &vtxbuf[vb_stride*i],
520 vtx_size);
521 }
522 }
523
524 DMA_COMMIT();
525 }
526
527 start += count;
528 n -= count;
529
530 prim |= BCI_CMD_DRAW_CONT;
531 }
532
533 return 0;
534}
535
536static int savage_dispatch_dma_idx(drm_savage_private_t *dev_priv,
537 const drm_savage_cmd_header_t *cmd_header,
538 const uint16_t __user *usr_idx,
539 const drm_buf_t *dmabuf)
540{
541 unsigned char reorder = 0;
542 unsigned int prim = cmd_header->idx.prim;
543 unsigned int skip = cmd_header->idx.skip;
544 unsigned int n = cmd_header->idx.count;
545 unsigned int i;
546 BCI_LOCALS;
547
548 if (!dmabuf) {
549 DRM_ERROR("called without dma buffers!\n");
550 return DRM_ERR(EINVAL);
551 }
552
553 if (!n)
554 return 0;
555
556 switch (prim) {
557 case SAVAGE_PRIM_TRILIST_201:
558 reorder = 1;
559 prim = SAVAGE_PRIM_TRILIST;
560 case SAVAGE_PRIM_TRILIST:
561 if (n % 3 != 0) {
562 DRM_ERROR("wrong number of indices %u in TRILIST\n",
563 n);
564 return DRM_ERR(EINVAL);
565 }
566 break;
567 case SAVAGE_PRIM_TRISTRIP:
568 case SAVAGE_PRIM_TRIFAN:
569 if (n < 3) {
570 DRM_ERROR("wrong number of indices %u in TRIFAN/STRIP\n",
571 n);
572 return DRM_ERR(EINVAL);
573 }
574 break;
575 default:
576 DRM_ERROR("invalid primitive type %u\n", prim);
577 return DRM_ERR(EINVAL);
578 }
579
580 if (S3_SAVAGE3D_SERIES(dev_priv->chipset)) {
581 if (skip != 0) {
582 DRM_ERROR("invalid skip flags 0x%04x for DMA\n",
583 skip);
584 return DRM_ERR(EINVAL);
585 }
586 } else {
587 unsigned int size = 10 - (skip & 1) - (skip >> 1 & 1) -
588 (skip >> 2 & 1) - (skip >> 3 & 1) - (skip >> 4 & 1) -
589 (skip >> 5 & 1) - (skip >> 6 & 1) - (skip >> 7 & 1);
590 if (skip > SAVAGE_SKIP_ALL_S4 || size != 8) {
591 DRM_ERROR("invalid skip flags 0x%04x for DMA\n",
592 skip);
593 return DRM_ERR(EINVAL);
594 }
595 if (reorder) {
596 DRM_ERROR("TRILIST_201 used on Savage4 hardware\n");
597 return DRM_ERR(EINVAL);
598 }
599 }
600
601 /* Vertex DMA doesn't work with command DMA at the same time,
602 * so we use BCI_... to submit commands here. Flush buffered
603 * faked DMA first. */
604 DMA_FLUSH();
605
606 if (dmabuf->bus_address != dev_priv->state.common.vbaddr) {
607 BEGIN_BCI(2);
608 BCI_SET_REGISTERS(SAVAGE_VERTBUFADDR, 1);
609 BCI_WRITE(dmabuf->bus_address | dev_priv->dma_type);
610 dev_priv->state.common.vbaddr = dmabuf->bus_address;
611 }
612 if (S3_SAVAGE3D_SERIES(dev_priv->chipset) && dev_priv->waiting) {
613 /* Workaround for what looks like a hardware bug. If a
614 * WAIT_3D_IDLE was emitted some time before the
615 * indexed drawing command then the engine will lock
616 * up. There are two known workarounds:
617 * WAIT_IDLE_EMPTY or emit at least 63 NOPs. */
618 BEGIN_BCI(63);
619 for (i = 0; i < 63; ++i)
620 BCI_WRITE(BCI_CMD_WAIT);
621 dev_priv->waiting = 0;
622 }
623
624 prim <<= 25;
625 while (n != 0) {
626 /* Can emit up to 255 indices (85 triangles) at once. */
627 unsigned int count = n > 255 ? 255 : n;
628 /* Is it ok to allocate 510 bytes on the stack in an ioctl? */
629 uint16_t idx[255];
630
631 /* Copy and check indices */
632 DRM_COPY_FROM_USER_UNCHECKED(idx, usr_idx, count*2);
633 for (i = 0; i < count; ++i) {
634 if (idx[i] > dmabuf->total/32) {
635 DRM_ERROR("idx[%u]=%u out of range (0-%u)\n",
636 i, idx[i], dmabuf->total/32);
637 return DRM_ERR(EINVAL);
638 }
639 }
640
641 if (reorder) {
642 /* Need to reorder indices for correct flat
643 * shading while preserving the clock sense
644 * for correct culling. Only on Savage3D. */
645 int reorder[3] = {2, -1, -1};
646
647 BEGIN_BCI((count+1+1)/2);
648 BCI_DRAW_INDICES_S3D(count, prim, idx[2]);
649
650 for (i = 1; i+1 < count; i += 2)
651 BCI_WRITE(idx[i + reorder[i % 3]] |
652 (idx[i+1 + reorder[(i+1) % 3]] << 16));
653 if (i < count)
654 BCI_WRITE(idx[i + reorder[i%3]]);
655 } else if (S3_SAVAGE3D_SERIES(dev_priv->chipset)) {
656 BEGIN_BCI((count+1+1)/2);
657 BCI_DRAW_INDICES_S3D(count, prim, idx[0]);
658
659 for (i = 1; i+1 < count; i += 2)
660 BCI_WRITE(idx[i] | (idx[i+1] << 16));
661 if (i < count)
662 BCI_WRITE(idx[i]);
663 } else {
664 BEGIN_BCI((count+2+1)/2);
665 BCI_DRAW_INDICES_S4(count, prim, skip);
666
667 for (i = 0; i+1 < count; i += 2)
668 BCI_WRITE(idx[i] | (idx[i+1] << 16));
669 if (i < count)
670 BCI_WRITE(idx[i]);
671 }
672
673 usr_idx += count;
674 n -= count;
675
676 prim |= BCI_CMD_DRAW_CONT;
677 }
678
679 return 0;
680}
681
682static int savage_dispatch_vb_idx(drm_savage_private_t *dev_priv,
683 const drm_savage_cmd_header_t *cmd_header,
684 const uint16_t __user *usr_idx,
685 const uint32_t __user *vtxbuf,
686 unsigned int vb_size,
687 unsigned int vb_stride)
688{
689 unsigned char reorder = 0;
690 unsigned int prim = cmd_header->idx.prim;
691 unsigned int skip = cmd_header->idx.skip;
692 unsigned int n = cmd_header->idx.count;
693 unsigned int vtx_size;
694 unsigned int i;
695 DMA_LOCALS;
696
697 if (!n)
698 return 0;
699
700 switch (prim) {
701 case SAVAGE_PRIM_TRILIST_201:
702 reorder = 1;
703 prim = SAVAGE_PRIM_TRILIST;
704 case SAVAGE_PRIM_TRILIST:
705 if (n % 3 != 0) {
706 DRM_ERROR("wrong number of indices %u in TRILIST\n",
707 n);
708 return DRM_ERR(EINVAL);
709 }
710 break;
711 case SAVAGE_PRIM_TRISTRIP:
712 case SAVAGE_PRIM_TRIFAN:
713 if (n < 3) {
714 DRM_ERROR("wrong number of indices %u in TRIFAN/STRIP\n",
715 n);
716 return DRM_ERR(EINVAL);
717 }
718 break;
719 default:
720 DRM_ERROR("invalid primitive type %u\n", prim);
721 return DRM_ERR(EINVAL);
722 }
723
724 if (S3_SAVAGE3D_SERIES(dev_priv->chipset)) {
725 if (skip > SAVAGE_SKIP_ALL_S3D) {
726 DRM_ERROR("invalid skip flags 0x%04x\n", skip);
727 return DRM_ERR(EINVAL);
728 }
729 vtx_size = 8; /* full vertex */
730 } else {
731 if (skip > SAVAGE_SKIP_ALL_S4) {
732 DRM_ERROR("invalid skip flags 0x%04x\n", skip);
733 return DRM_ERR(EINVAL);
734 }
735 vtx_size = 10; /* full vertex */
736 }
737
738 vtx_size -= (skip & 1) + (skip >> 1 & 1) +
739 (skip >> 2 & 1) + (skip >> 3 & 1) + (skip >> 4 & 1) +
740 (skip >> 5 & 1) + (skip >> 6 & 1) + (skip >> 7 & 1);
741
742 if (vtx_size > vb_stride) {
743 DRM_ERROR("vertex size greater than vb stride (%u > %u)\n",
744 vtx_size, vb_stride);
745 return DRM_ERR(EINVAL);
746 }
747
748 prim <<= 25;
749 while (n != 0) {
750 /* Can emit up to 255 vertices (85 triangles) at once. */
751 unsigned int count = n > 255 ? 255 : n;
752 /* Is it ok to allocate 510 bytes on the stack in an ioctl? */
753 uint16_t idx[255];
754
755 /* Copy and check indices */
756 DRM_COPY_FROM_USER_UNCHECKED(idx, usr_idx, count*2);
757 for (i = 0; i < count; ++i) {
758 if (idx[i] > vb_size / (vb_stride*4)) {
759 DRM_ERROR("idx[%u]=%u out of range (0-%u)\n",
760 i, idx[i], vb_size / (vb_stride*4));
761 return DRM_ERR(EINVAL);
762 }
763 }
764
765 if (reorder) {
766 /* Need to reorder vertices for correct flat
767 * shading while preserving the clock sense
768 * for correct culling. Only on Savage3D. */
769 int reorder[3] = {2, -1, -1};
770
771 BEGIN_DMA(count*vtx_size+1);
772 DMA_DRAW_PRIMITIVE(count, prim, skip);
773
774 for (i = 0; i < count; ++i) {
775 unsigned int j = idx[i + reorder[i % 3]];
776 DMA_COPY_FROM_USER(&vtxbuf[vb_stride*j],
777 vtx_size);
778 }
779
780 DMA_COMMIT();
781 } else {
782 BEGIN_DMA(count*vtx_size+1);
783 DMA_DRAW_PRIMITIVE(count, prim, skip);
784
785 for (i = 0; i < count; ++i) {
786 unsigned int j = idx[i];
787 DMA_COPY_FROM_USER(&vtxbuf[vb_stride*j],
788 vtx_size);
789 }
790
791 DMA_COMMIT();
792 }
793
794 usr_idx += count;
795 n -= count;
796
797 prim |= BCI_CMD_DRAW_CONT;
798 }
799
800 return 0;
801}
802
803static int savage_dispatch_clear(drm_savage_private_t *dev_priv,
804 const drm_savage_cmd_header_t *cmd_header,
805 const drm_savage_cmd_header_t __user *data,
806 unsigned int nbox,
807 const drm_clip_rect_t __user *usr_boxes)
808{
809 unsigned int flags = cmd_header->clear0.flags, mask, value;
810 unsigned int clear_cmd;
811 unsigned int i, nbufs;
812 DMA_LOCALS;
813
814 if (nbox == 0)
815 return 0;
816
817 DRM_GET_USER_UNCHECKED(mask, &((const drm_savage_cmd_header_t*)data)
818 ->clear1.mask);
819 DRM_GET_USER_UNCHECKED(value, &((const drm_savage_cmd_header_t*)data)
820 ->clear1.value);
821
822 clear_cmd = BCI_CMD_RECT | BCI_CMD_RECT_XP | BCI_CMD_RECT_YP |
823 BCI_CMD_SEND_COLOR | BCI_CMD_DEST_PBD_NEW;
824 BCI_CMD_SET_ROP(clear_cmd,0xCC);
825
826 nbufs = ((flags & SAVAGE_FRONT) ? 1 : 0) +
827 ((flags & SAVAGE_BACK) ? 1 : 0) +
828 ((flags & SAVAGE_DEPTH) ? 1 : 0);
829 if (nbufs == 0)
830 return 0;
831
832 if (mask != 0xffffffff) {
833 /* set mask */
834 BEGIN_DMA(2);
835 DMA_SET_REGISTERS(SAVAGE_BITPLANEWTMASK, 1);
836 DMA_WRITE(mask);
837 DMA_COMMIT();
838 }
839 for (i = 0; i < nbox; ++i) {
840 drm_clip_rect_t box;
841 unsigned int x, y, w, h;
842 unsigned int buf;
843 DRM_COPY_FROM_USER_UNCHECKED(&box, &usr_boxes[i], sizeof(box));
844 x = box.x1, y = box.y1;
845 w = box.x2 - box.x1;
846 h = box.y2 - box.y1;
847 BEGIN_DMA(nbufs*6);
848 for (buf = SAVAGE_FRONT; buf <= SAVAGE_DEPTH; buf <<= 1) {
849 if (!(flags & buf))
850 continue;
851 DMA_WRITE(clear_cmd);
852 switch(buf) {
853 case SAVAGE_FRONT:
854 DMA_WRITE(dev_priv->front_offset);
855 DMA_WRITE(dev_priv->front_bd);
856 break;
857 case SAVAGE_BACK:
858 DMA_WRITE(dev_priv->back_offset);
859 DMA_WRITE(dev_priv->back_bd);
860 break;
861 case SAVAGE_DEPTH:
862 DMA_WRITE(dev_priv->depth_offset);
863 DMA_WRITE(dev_priv->depth_bd);
864 break;
865 }
866 DMA_WRITE(value);
867 DMA_WRITE(BCI_X_Y(x, y));
868 DMA_WRITE(BCI_W_H(w, h));
869 }
870 DMA_COMMIT();
871 }
872 if (mask != 0xffffffff) {
873 /* reset mask */
874 BEGIN_DMA(2);
875 DMA_SET_REGISTERS(SAVAGE_BITPLANEWTMASK, 1);
876 DMA_WRITE(0xffffffff);
877 DMA_COMMIT();
878 }
879
880 return 0;
881}
882
883static int savage_dispatch_swap(drm_savage_private_t *dev_priv,
884 unsigned int nbox,
885 const drm_clip_rect_t __user *usr_boxes)
886{
887 unsigned int swap_cmd;
888 unsigned int i;
889 DMA_LOCALS;
890
891 if (nbox == 0)
892 return 0;
893
894 swap_cmd = BCI_CMD_RECT | BCI_CMD_RECT_XP | BCI_CMD_RECT_YP |
895 BCI_CMD_SRC_PBD_COLOR_NEW | BCI_CMD_DEST_GBD;
896 BCI_CMD_SET_ROP(swap_cmd,0xCC);
897
898 for (i = 0; i < nbox; ++i) {
899 drm_clip_rect_t box;
900 DRM_COPY_FROM_USER_UNCHECKED(&box, &usr_boxes[i], sizeof(box));
901
902 BEGIN_DMA(6);
903 DMA_WRITE(swap_cmd);
904 DMA_WRITE(dev_priv->back_offset);
905 DMA_WRITE(dev_priv->back_bd);
906 DMA_WRITE(BCI_X_Y(box.x1, box.y1));
907 DMA_WRITE(BCI_X_Y(box.x1, box.y1));
908 DMA_WRITE(BCI_W_H(box.x2-box.x1, box.y2-box.y1));
909 DMA_COMMIT();
910 }
911
912 return 0;
913}
914
915static int savage_dispatch_draw(drm_savage_private_t *dev_priv,
916 const drm_savage_cmd_header_t __user *start,
917 const drm_savage_cmd_header_t __user *end,
918 const drm_buf_t *dmabuf,
919 const unsigned int __user *usr_vtxbuf,
920 unsigned int vb_size, unsigned int vb_stride,
921 unsigned int nbox,
922 const drm_clip_rect_t __user *usr_boxes)
923{
924 unsigned int i, j;
925 int ret;
926
927 for (i = 0; i < nbox; ++i) {
928 drm_clip_rect_t box;
929 const drm_savage_cmd_header_t __user *usr_cmdbuf;
930 DRM_COPY_FROM_USER_UNCHECKED(&box, &usr_boxes[i], sizeof(box));
931 dev_priv->emit_clip_rect(dev_priv, &box);
932
933 usr_cmdbuf = start;
934 while (usr_cmdbuf < end) {
935 drm_savage_cmd_header_t cmd_header;
936 DRM_COPY_FROM_USER_UNCHECKED(&cmd_header, usr_cmdbuf,
937 sizeof(cmd_header));
938 usr_cmdbuf++;
939 switch (cmd_header.cmd.cmd) {
940 case SAVAGE_CMD_DMA_PRIM:
941 ret = savage_dispatch_dma_prim(
942 dev_priv, &cmd_header, dmabuf);
943 break;
944 case SAVAGE_CMD_VB_PRIM:
945 ret = savage_dispatch_vb_prim(
946 dev_priv, &cmd_header,
947 (const uint32_t __user *)usr_vtxbuf,
948 vb_size, vb_stride);
949 break;
950 case SAVAGE_CMD_DMA_IDX:
951 j = (cmd_header.idx.count + 3) / 4;
952 /* j was check in savage_bci_cmdbuf */
953 ret = savage_dispatch_dma_idx(
954 dev_priv, &cmd_header,
955 (const uint16_t __user *)usr_cmdbuf,
956 dmabuf);
957 usr_cmdbuf += j;
958 break;
959 case SAVAGE_CMD_VB_IDX:
960 j = (cmd_header.idx.count + 3) / 4;
961 /* j was check in savage_bci_cmdbuf */
962 ret = savage_dispatch_vb_idx(
963 dev_priv, &cmd_header,
964 (const uint16_t __user *)usr_cmdbuf,
965 (const uint32_t __user *)usr_vtxbuf,
966 vb_size, vb_stride);
967 usr_cmdbuf += j;
968 break;
969 default:
970 /* What's the best return code? EFAULT? */
971 DRM_ERROR("IMPLEMENTATION ERROR: "
972 "non-drawing-command %d\n",
973 cmd_header.cmd.cmd);
974 return DRM_ERR(EINVAL);
975 }
976
977 if (ret != 0)
978 return ret;
979 }
980 }
981
982 return 0;
983}
984
985int savage_bci_cmdbuf(DRM_IOCTL_ARGS)
986{
987 DRM_DEVICE;
988 drm_savage_private_t *dev_priv = dev->dev_private;
989 drm_device_dma_t *dma = dev->dma;
990 drm_buf_t *dmabuf;
991 drm_savage_cmdbuf_t cmdbuf;
992 drm_savage_cmd_header_t __user *usr_cmdbuf;
993 drm_savage_cmd_header_t __user *first_draw_cmd;
994 unsigned int __user *usr_vtxbuf;
995 drm_clip_rect_t __user *usr_boxes;
996 unsigned int i, j;
997 int ret = 0;
998
999 DRM_DEBUG("\n");
1000
1001 LOCK_TEST_WITH_RETURN(dev, filp);
1002
1003 DRM_COPY_FROM_USER_IOCTL(cmdbuf, (drm_savage_cmdbuf_t __user *)data,
1004 sizeof(cmdbuf));
1005
1006 if (dma && dma->buflist) {
1007 if (cmdbuf.dma_idx > dma->buf_count) {
1008 DRM_ERROR("vertex buffer index %u out of range (0-%u)\n",
1009 cmdbuf.dma_idx, dma->buf_count-1);
1010 return DRM_ERR(EINVAL);
1011 }
1012 dmabuf = dma->buflist[cmdbuf.dma_idx];
1013 } else {
1014 dmabuf = NULL;
1015 }
1016
1017 usr_cmdbuf = (drm_savage_cmd_header_t __user *)cmdbuf.cmd_addr;
1018 usr_vtxbuf = (unsigned int __user *)cmdbuf.vb_addr;
1019 usr_boxes = (drm_clip_rect_t __user *)cmdbuf.box_addr;
1020 if ((cmdbuf.size && DRM_VERIFYAREA_READ(usr_cmdbuf, cmdbuf.size*8)) ||
1021 (cmdbuf.vb_size && DRM_VERIFYAREA_READ(
1022 usr_vtxbuf, cmdbuf.vb_size)) ||
1023 (cmdbuf.nbox && DRM_VERIFYAREA_READ(
1024 usr_boxes, cmdbuf.nbox*sizeof(drm_clip_rect_t))))
1025 return DRM_ERR(EFAULT);
1026
1027 /* Make sure writes to DMA buffers are finished before sending
1028 * DMA commands to the graphics hardware. */
1029 DRM_MEMORYBARRIER();
1030
1031 /* Coming from user space. Don't know if the Xserver has
1032 * emitted wait commands. Assuming the worst. */
1033 dev_priv->waiting = 1;
1034
1035 i = 0;
1036 first_draw_cmd = NULL;
1037 while (i < cmdbuf.size) {
1038 drm_savage_cmd_header_t cmd_header;
1039 DRM_COPY_FROM_USER_UNCHECKED(&cmd_header, usr_cmdbuf,
1040 sizeof(cmd_header));
1041 usr_cmdbuf++;
1042 i++;
1043
1044 /* Group drawing commands with same state to minimize
1045 * iterations over clip rects. */
1046 j = 0;
1047 switch (cmd_header.cmd.cmd) {
1048 case SAVAGE_CMD_DMA_IDX:
1049 case SAVAGE_CMD_VB_IDX:
1050 j = (cmd_header.idx.count + 3) / 4;
1051 if (i + j > cmdbuf.size) {
1052 DRM_ERROR("indexed drawing command extends "
1053 "beyond end of command buffer\n");
1054 DMA_FLUSH();
1055 return DRM_ERR(EINVAL);
1056 }
1057 /* fall through */
1058 case SAVAGE_CMD_DMA_PRIM:
1059 case SAVAGE_CMD_VB_PRIM:
1060 if (!first_draw_cmd)
1061 first_draw_cmd = usr_cmdbuf-1;
1062 usr_cmdbuf += j;
1063 i += j;
1064 break;
1065 default:
1066 if (first_draw_cmd) {
1067 ret = savage_dispatch_draw (
1068 dev_priv, first_draw_cmd, usr_cmdbuf-1,
1069 dmabuf, usr_vtxbuf, cmdbuf.vb_size,
1070 cmdbuf.vb_stride,
1071 cmdbuf.nbox, usr_boxes);
1072 if (ret != 0)
1073 return ret;
1074 first_draw_cmd = NULL;
1075 }
1076 }
1077 if (first_draw_cmd)
1078 continue;
1079
1080 switch (cmd_header.cmd.cmd) {
1081 case SAVAGE_CMD_STATE:
1082 j = (cmd_header.state.count + 1) / 2;
1083 if (i + j > cmdbuf.size) {
1084 DRM_ERROR("command SAVAGE_CMD_STATE extends "
1085 "beyond end of command buffer\n");
1086 DMA_FLUSH();
1087 return DRM_ERR(EINVAL);
1088 }
1089 ret = savage_dispatch_state(
1090 dev_priv, &cmd_header,
1091 (uint32_t __user *)usr_cmdbuf);
1092 usr_cmdbuf += j;
1093 i += j;
1094 break;
1095 case SAVAGE_CMD_CLEAR:
1096 if (i + 1 > cmdbuf.size) {
1097 DRM_ERROR("command SAVAGE_CMD_CLEAR extends "
1098 "beyond end of command buffer\n");
1099 DMA_FLUSH();
1100 return DRM_ERR(EINVAL);
1101 }
1102 ret = savage_dispatch_clear(dev_priv, &cmd_header,
1103 usr_cmdbuf,
1104 cmdbuf.nbox, usr_boxes);
1105 usr_cmdbuf++;
1106 i++;
1107 break;
1108 case SAVAGE_CMD_SWAP:
1109 ret = savage_dispatch_swap(dev_priv,
1110 cmdbuf.nbox, usr_boxes);
1111 break;
1112 default:
1113 DRM_ERROR("invalid command 0x%x\n", cmd_header.cmd.cmd);
1114 DMA_FLUSH();
1115 return DRM_ERR(EINVAL);
1116 }
1117
1118 if (ret != 0) {
1119 DMA_FLUSH();
1120 return ret;
1121 }
1122 }
1123
1124 if (first_draw_cmd) {
1125 ret = savage_dispatch_draw (
1126 dev_priv, first_draw_cmd, usr_cmdbuf, dmabuf,
1127 usr_vtxbuf, cmdbuf.vb_size, cmdbuf.vb_stride,
1128 cmdbuf.nbox, usr_boxes);
1129 if (ret != 0) {
1130 DMA_FLUSH();
1131 return ret;
1132 }
1133 }
1134
1135 DMA_FLUSH();
1136
1137 if (dmabuf && cmdbuf.discard) {
1138 drm_savage_buf_priv_t *buf_priv = dmabuf->dev_private;
1139 uint16_t event;
1140 event = savage_bci_emit_event(dev_priv, SAVAGE_WAIT_3D);
1141 SET_AGE(&buf_priv->age, event, dev_priv->event_wrap);
1142 savage_freelist_put(dev, dmabuf);
1143 }
1144
1145 return 0;
1146}
diff --git a/drivers/char/hvc_vio.c b/drivers/char/hvc_vio.c
index 60bb9152b832..78d681dc35a8 100644
--- a/drivers/char/hvc_vio.c
+++ b/drivers/char/hvc_vio.c
@@ -39,7 +39,7 @@ char hvc_driver_name[] = "hvc_console";
39 39
40static struct vio_device_id hvc_driver_table[] __devinitdata = { 40static struct vio_device_id hvc_driver_table[] __devinitdata = {
41 {"serial", "hvterm1"}, 41 {"serial", "hvterm1"},
42 { NULL, } 42 { "", "" }
43}; 43};
44MODULE_DEVICE_TABLE(vio, hvc_driver_table); 44MODULE_DEVICE_TABLE(vio, hvc_driver_table);
45 45
diff --git a/drivers/char/hvcs.c b/drivers/char/hvcs.c
index 3236d2404905..f47f009f9259 100644
--- a/drivers/char/hvcs.c
+++ b/drivers/char/hvcs.c
@@ -527,7 +527,7 @@ static int khvcsd(void *unused)
527 527
528static struct vio_device_id hvcs_driver_table[] __devinitdata= { 528static struct vio_device_id hvcs_driver_table[] __devinitdata= {
529 {"serial-server", "hvterm2"}, 529 {"serial-server", "hvterm2"},
530 { NULL, } 530 { "", "" }
531}; 531};
532MODULE_DEVICE_TABLE(vio, hvcs_driver_table); 532MODULE_DEVICE_TABLE(vio, hvcs_driver_table);
533 533
diff --git a/drivers/char/mwave/mwavedd.c b/drivers/char/mwave/mwavedd.c
index d568991ac6b3..8666171e187b 100644
--- a/drivers/char/mwave/mwavedd.c
+++ b/drivers/char/mwave/mwavedd.c
@@ -57,6 +57,7 @@
57#include <linux/sched.h> 57#include <linux/sched.h>
58#include <linux/spinlock.h> 58#include <linux/spinlock.h>
59#include <linux/delay.h> 59#include <linux/delay.h>
60#include <linux/serial_8250.h>
60#include "smapi.h" 61#include "smapi.h"
61#include "mwavedd.h" 62#include "mwavedd.h"
62#include "3780i.h" 63#include "3780i.h"
@@ -410,8 +411,8 @@ static ssize_t mwave_write(struct file *file, const char __user *buf,
410 411
411static int register_serial_portandirq(unsigned int port, int irq) 412static int register_serial_portandirq(unsigned int port, int irq)
412{ 413{
413 struct serial_struct serial; 414 struct uart_port uart;
414 415
415 switch ( port ) { 416 switch ( port ) {
416 case 0x3f8: 417 case 0x3f8:
417 case 0x2f8: 418 case 0x2f8:
@@ -442,12 +443,14 @@ static int register_serial_portandirq(unsigned int port, int irq)
442 } /* switch */ 443 } /* switch */
443 /* irq is okay */ 444 /* irq is okay */
444 445
445 memset(&serial, 0, sizeof(serial)); 446 memset(&uart, 0, sizeof(struct uart_port));
446 serial.port = port; 447
447 serial.irq = irq; 448 uart.uartclk = 1843200;
448 serial.flags = ASYNC_SHARE_IRQ; 449 uart.iobase = port;
449 450 uart.irq = irq;
450 return register_serial(&serial); 451 uart.iotype = UPIO_PORT;
452 uart.flags = UPF_SHARE_IRQ;
453 return serial8250_register_port(&uart);
451} 454}
452 455
453 456
@@ -523,7 +526,7 @@ static void mwave_exit(void)
523#endif 526#endif
524 527
525 if ( pDrvData->sLine >= 0 ) { 528 if ( pDrvData->sLine >= 0 ) {
526 unregister_serial(pDrvData->sLine); 529 serial8250_unregister_port(pDrvData->sLine);
527 } 530 }
528 if (pDrvData->bMwaveDevRegistered) { 531 if (pDrvData->bMwaveDevRegistered) {
529 misc_deregister(&mwave_misc_dev); 532 misc_deregister(&mwave_misc_dev);
diff --git a/drivers/char/random.c b/drivers/char/random.c
index 6b11d6b2129f..7999da25fe40 100644
--- a/drivers/char/random.c
+++ b/drivers/char/random.c
@@ -1589,6 +1589,40 @@ u32 secure_tcpv6_port_ephemeral(const __u32 *saddr, const __u32 *daddr, __u16 dp
1589EXPORT_SYMBOL(secure_tcpv6_port_ephemeral); 1589EXPORT_SYMBOL(secure_tcpv6_port_ephemeral);
1590#endif 1590#endif
1591 1591
1592#if defined(CONFIG_IP_DCCP) || defined(CONFIG_IP_DCCP_MODULE)
1593/* Similar to secure_tcp_sequence_number but generate a 48 bit value
1594 * bit's 32-47 increase every key exchange
1595 * 0-31 hash(source, dest)
1596 */
1597u64 secure_dccp_sequence_number(__u32 saddr, __u32 daddr,
1598 __u16 sport, __u16 dport)
1599{
1600 struct timeval tv;
1601 u64 seq;
1602 __u32 hash[4];
1603 struct keydata *keyptr = get_keyptr();
1604
1605 hash[0] = saddr;
1606 hash[1] = daddr;
1607 hash[2] = (sport << 16) + dport;
1608 hash[3] = keyptr->secret[11];
1609
1610 seq = half_md4_transform(hash, keyptr->secret);
1611 seq |= ((u64)keyptr->count) << (32 - HASH_BITS);
1612
1613 do_gettimeofday(&tv);
1614 seq += tv.tv_usec + tv.tv_sec * 1000000;
1615 seq &= (1ull << 48) - 1;
1616#if 0
1617 printk("dccp init_seq(%lx, %lx, %d, %d) = %d\n",
1618 saddr, daddr, sport, dport, seq);
1619#endif
1620 return seq;
1621}
1622
1623EXPORT_SYMBOL(secure_dccp_sequence_number);
1624#endif
1625
1592#endif /* CONFIG_INET */ 1626#endif /* CONFIG_INET */
1593 1627
1594 1628
diff --git a/drivers/char/snsc_event.c b/drivers/char/snsc_event.c
index d692af57213a..baaa365285fa 100644
--- a/drivers/char/snsc_event.c
+++ b/drivers/char/snsc_event.c
@@ -19,6 +19,7 @@
19#include <linux/sched.h> 19#include <linux/sched.h>
20#include <linux/byteorder/generic.h> 20#include <linux/byteorder/generic.h>
21#include <asm/sn/sn_sal.h> 21#include <asm/sn/sn_sal.h>
22#include <asm/unaligned.h>
22#include "snsc.h" 23#include "snsc.h"
23 24
24static struct subch_data_s *event_sd; 25static struct subch_data_s *event_sd;
@@ -62,13 +63,16 @@ static int
62scdrv_parse_event(char *event, int *src, int *code, int *esp_code, char *desc) 63scdrv_parse_event(char *event, int *src, int *code, int *esp_code, char *desc)
63{ 64{
64 char *desc_end; 65 char *desc_end;
66 __be32 from_buf;
65 67
66 /* record event source address */ 68 /* record event source address */
67 *src = be32_to_cpup((__be32 *)event); 69 from_buf = get_unaligned((__be32 *)event);
70 *src = be32_to_cpup(&from_buf);
68 event += 4; /* move on to event code */ 71 event += 4; /* move on to event code */
69 72
70 /* record the system controller's event code */ 73 /* record the system controller's event code */
71 *code = be32_to_cpup((__be32 *)event); 74 from_buf = get_unaligned((__be32 *)event);
75 *code = be32_to_cpup(&from_buf);
72 event += 4; /* move on to event arguments */ 76 event += 4; /* move on to event arguments */
73 77
74 /* how many arguments are in the packet? */ 78 /* how many arguments are in the packet? */
@@ -82,7 +86,8 @@ scdrv_parse_event(char *event, int *src, int *code, int *esp_code, char *desc)
82 /* not an integer argument, so give up */ 86 /* not an integer argument, so give up */
83 return -1; 87 return -1;
84 } 88 }
85 *esp_code = be32_to_cpup((__be32 *)event); 89 from_buf = get_unaligned((__be32 *)event);
90 *esp_code = be32_to_cpup(&from_buf);
86 event += 4; 91 event += 4;
87 92
88 /* parse out the event description */ 93 /* parse out the event description */
diff --git a/drivers/char/viotape.c b/drivers/char/viotape.c
index 4764b4f9555d..0aff45fac2e6 100644
--- a/drivers/char/viotape.c
+++ b/drivers/char/viotape.c
@@ -991,7 +991,7 @@ static int viotape_remove(struct vio_dev *vdev)
991 */ 991 */
992static struct vio_device_id viotape_device_table[] __devinitdata = { 992static struct vio_device_id viotape_device_table[] __devinitdata = {
993 { "viotape", "" }, 993 { "viotape", "" },
994 { 0, } 994 { "", "" }
995}; 995};
996 996
997MODULE_DEVICE_TABLE(vio, viotape_device_table); 997MODULE_DEVICE_TABLE(vio, viotape_device_table);
diff --git a/drivers/ieee1394/ieee1394_core.c b/drivers/ieee1394/ieee1394_core.c
index b248d89de8b4..d633770fac8e 100644
--- a/drivers/ieee1394/ieee1394_core.c
+++ b/drivers/ieee1394/ieee1394_core.c
@@ -681,7 +681,7 @@ static void handle_packet_response(struct hpsb_host *host, int tcode,
681 return; 681 return;
682 } 682 }
683 683
684 __skb_unlink(skb, skb->list); 684 __skb_unlink(skb, &host->pending_packet_queue);
685 685
686 if (packet->state == hpsb_queued) { 686 if (packet->state == hpsb_queued) {
687 packet->sendtime = jiffies; 687 packet->sendtime = jiffies;
@@ -989,7 +989,7 @@ void abort_timedouts(unsigned long __opaque)
989 packet = (struct hpsb_packet *)skb->data; 989 packet = (struct hpsb_packet *)skb->data;
990 990
991 if (time_before(packet->sendtime + expire, jiffies)) { 991 if (time_before(packet->sendtime + expire, jiffies)) {
992 __skb_unlink(skb, skb->list); 992 __skb_unlink(skb, &host->pending_packet_queue);
993 packet->state = hpsb_complete; 993 packet->state = hpsb_complete;
994 packet->ack_code = ACKX_TIMEOUT; 994 packet->ack_code = ACKX_TIMEOUT;
995 queue_packet_complete(packet); 995 queue_packet_complete(packet);
diff --git a/drivers/isdn/act2000/capi.c b/drivers/isdn/act2000/capi.c
index afa46681f983..6ae6eb322111 100644
--- a/drivers/isdn/act2000/capi.c
+++ b/drivers/isdn/act2000/capi.c
@@ -606,7 +606,7 @@ handle_ack(act2000_card *card, act2000_chan *chan, __u8 blocknr) {
606 if ((((m->msg.data_b3_req.fakencci >> 8) & 0xff) == chan->ncci) && 606 if ((((m->msg.data_b3_req.fakencci >> 8) & 0xff) == chan->ncci) &&
607 (m->msg.data_b3_req.blocknr == blocknr)) { 607 (m->msg.data_b3_req.blocknr == blocknr)) {
608 /* found corresponding DATA_B3_REQ */ 608 /* found corresponding DATA_B3_REQ */
609 skb_unlink(tmp); 609 skb_unlink(tmp, &card->ackq);
610 chan->queued -= m->msg.data_b3_req.datalen; 610 chan->queued -= m->msg.data_b3_req.datalen;
611 if (m->msg.data_b3_req.flags) 611 if (m->msg.data_b3_req.flags)
612 ret = m->msg.data_b3_req.datalen; 612 ret = m->msg.data_b3_req.datalen;
diff --git a/drivers/isdn/i4l/isdn_net.c b/drivers/isdn/i4l/isdn_net.c
index f30e8e63ae0d..96c115e13389 100644
--- a/drivers/isdn/i4l/isdn_net.c
+++ b/drivers/isdn/i4l/isdn_net.c
@@ -1786,7 +1786,6 @@ isdn_net_receive(struct net_device *ndev, struct sk_buff *skb)
1786 lp->stats.rx_bytes += skb->len; 1786 lp->stats.rx_bytes += skb->len;
1787 } 1787 }
1788 skb->dev = ndev; 1788 skb->dev = ndev;
1789 skb->input_dev = ndev;
1790 skb->pkt_type = PACKET_HOST; 1789 skb->pkt_type = PACKET_HOST;
1791 skb->mac.raw = skb->data; 1790 skb->mac.raw = skb->data;
1792#ifdef ISDN_DEBUG_NET_DUMP 1791#ifdef ISDN_DEBUG_NET_DUMP
diff --git a/drivers/isdn/i4l/isdn_ppp.c b/drivers/isdn/i4l/isdn_ppp.c
index 260a323a96d3..d97a9be5469c 100644
--- a/drivers/isdn/i4l/isdn_ppp.c
+++ b/drivers/isdn/i4l/isdn_ppp.c
@@ -1177,7 +1177,6 @@ isdn_ppp_push_higher(isdn_net_dev * net_dev, isdn_net_local * lp, struct sk_buff
1177 mlp->huptimer = 0; 1177 mlp->huptimer = 0;
1178#endif /* CONFIG_IPPP_FILTER */ 1178#endif /* CONFIG_IPPP_FILTER */
1179 skb->dev = dev; 1179 skb->dev = dev;
1180 skb->input_dev = dev;
1181 skb->mac.raw = skb->data; 1180 skb->mac.raw = skb->data;
1182 netif_rx(skb); 1181 netif_rx(skb);
1183 /* net_dev->local->stats.rx_packets++; done in isdn_net.c */ 1182 /* net_dev->local->stats.rx_packets++; done in isdn_net.c */
diff --git a/drivers/media/dvb/ttpci/Kconfig b/drivers/media/dvb/ttpci/Kconfig
index bf3c011d2cfb..d8bf65877897 100644
--- a/drivers/media/dvb/ttpci/Kconfig
+++ b/drivers/media/dvb/ttpci/Kconfig
@@ -102,6 +102,9 @@ config DVB_BUDGET_AV
102 select VIDEO_DEV 102 select VIDEO_DEV
103 select VIDEO_SAA7146_VV 103 select VIDEO_SAA7146_VV
104 select DVB_STV0299 104 select DVB_STV0299
105 select DVB_TDA1004X
106 select DVB_TDA10021
107 select FW_LOADER
105 help 108 help
106 Support for simple SAA7146 based DVB cards 109 Support for simple SAA7146 based DVB cards
107 (so called Budget- or Nova-PCI cards) without onboard 110 (so called Budget- or Nova-PCI cards) without onboard
diff --git a/drivers/misc/Kconfig b/drivers/misc/Kconfig
index 7fc692a8f5b0..dea6589d1533 100644
--- a/drivers/misc/Kconfig
+++ b/drivers/misc/Kconfig
@@ -6,7 +6,7 @@ menu "Misc devices"
6 6
7config IBM_ASM 7config IBM_ASM
8 tristate "Device driver for IBM RSA service processor" 8 tristate "Device driver for IBM RSA service processor"
9 depends on X86 && PCI && EXPERIMENTAL 9 depends on X86 && PCI && EXPERIMENTAL && BROKEN
10 ---help--- 10 ---help---
11 This option enables device driver support for in-band access to the 11 This option enables device driver support for in-band access to the
12 IBM RSA (Condor) service processor in eServer xSeries systems. 12 IBM RSA (Condor) service processor in eServer xSeries systems.
diff --git a/drivers/net/Kconfig b/drivers/net/Kconfig
index 79e8aa6f2b9e..7d8bcb38797a 100644
--- a/drivers/net/Kconfig
+++ b/drivers/net/Kconfig
@@ -447,7 +447,7 @@ config NET_SB1250_MAC
447 447
448config SGI_IOC3_ETH 448config SGI_IOC3_ETH
449 bool "SGI IOC3 Ethernet" 449 bool "SGI IOC3 Ethernet"
450 depends on NET_ETHERNET && PCI && SGI_IP27 450 depends on NET_ETHERNET && PCI && SGI_IP27 && BROKEN
451 select CRC32 451 select CRC32
452 select MII 452 select MII
453 help 453 help
@@ -1923,6 +1923,17 @@ config R8169_VLAN
1923 1923
1924 If in doubt, say Y. 1924 If in doubt, say Y.
1925 1925
1926config SIS190
1927 tristate "SiS190 gigabit ethernet support"
1928 depends on PCI
1929 select CRC32
1930 select MII
1931 ---help---
1932 Say Y here if you have a SiS 190 PCI Gigabit Ethernet adapter.
1933
1934 To compile this driver as a module, choose M here: the module
1935 will be called sis190. This is recommended.
1936
1926config SKGE 1937config SKGE
1927 tristate "New SysKonnect GigaEthernet support (EXPERIMENTAL)" 1938 tristate "New SysKonnect GigaEthernet support (EXPERIMENTAL)"
1928 depends on PCI && EXPERIMENTAL 1939 depends on PCI && EXPERIMENTAL
@@ -2093,6 +2104,25 @@ endmenu
2093menu "Ethernet (10000 Mbit)" 2104menu "Ethernet (10000 Mbit)"
2094 depends on !UML 2105 depends on !UML
2095 2106
2107config CHELSIO_T1
2108 tristate "Chelsio 10Gb Ethernet support"
2109 depends on PCI
2110 help
2111 This driver supports Chelsio N110 and N210 models 10Gb Ethernet
2112 cards. More information about adapter features and performance
2113 tuning is in <file:Documentation/networking/cxgb.txt>.
2114
2115 For general information about Chelsio and our products, visit
2116 our website at <http://www.chelsio.com>.
2117
2118 For customer support, please visit our customer support page at
2119 <http://www.chelsio.com/support.htm>.
2120
2121 Please send feedback to <linux-bugs@chelsio.com>.
2122
2123 To compile this driver as a module, choose M here: the module
2124 will be called cxgb.
2125
2096config IXGB 2126config IXGB
2097 tristate "Intel(R) PRO/10GbE support" 2127 tristate "Intel(R) PRO/10GbE support"
2098 depends on PCI 2128 depends on PCI
diff --git a/drivers/net/Makefile b/drivers/net/Makefile
index a369ae284a9a..5baafcd55610 100644
--- a/drivers/net/Makefile
+++ b/drivers/net/Makefile
@@ -9,6 +9,7 @@ endif
9obj-$(CONFIG_E1000) += e1000/ 9obj-$(CONFIG_E1000) += e1000/
10obj-$(CONFIG_IBM_EMAC) += ibm_emac/ 10obj-$(CONFIG_IBM_EMAC) += ibm_emac/
11obj-$(CONFIG_IXGB) += ixgb/ 11obj-$(CONFIG_IXGB) += ixgb/
12obj-$(CONFIG_CHELSIO_T1) += chelsio/
12obj-$(CONFIG_BONDING) += bonding/ 13obj-$(CONFIG_BONDING) += bonding/
13obj-$(CONFIG_GIANFAR) += gianfar_driver.o 14obj-$(CONFIG_GIANFAR) += gianfar_driver.o
14 15
@@ -42,6 +43,7 @@ obj-$(CONFIG_EEPRO100) += eepro100.o
42obj-$(CONFIG_E100) += e100.o 43obj-$(CONFIG_E100) += e100.o
43obj-$(CONFIG_TLAN) += tlan.o 44obj-$(CONFIG_TLAN) += tlan.o
44obj-$(CONFIG_EPIC100) += epic100.o 45obj-$(CONFIG_EPIC100) += epic100.o
46obj-$(CONFIG_SIS190) += sis190.o
45obj-$(CONFIG_SIS900) += sis900.o 47obj-$(CONFIG_SIS900) += sis900.o
46obj-$(CONFIG_YELLOWFIN) += yellowfin.o 48obj-$(CONFIG_YELLOWFIN) += yellowfin.o
47obj-$(CONFIG_ACENIC) += acenic.o 49obj-$(CONFIG_ACENIC) += acenic.o
diff --git a/drivers/net/bnx2.c b/drivers/net/bnx2.c
index 8acc655ec1e8..7babf6af4e28 100644
--- a/drivers/net/bnx2.c
+++ b/drivers/net/bnx2.c
@@ -14,8 +14,8 @@
14 14
15#define DRV_MODULE_NAME "bnx2" 15#define DRV_MODULE_NAME "bnx2"
16#define PFX DRV_MODULE_NAME ": " 16#define PFX DRV_MODULE_NAME ": "
17#define DRV_MODULE_VERSION "1.2.19" 17#define DRV_MODULE_VERSION "1.2.20"
18#define DRV_MODULE_RELDATE "May 23, 2005" 18#define DRV_MODULE_RELDATE "August 22, 2005"
19 19
20#define RUN_AT(x) (jiffies + (x)) 20#define RUN_AT(x) (jiffies + (x))
21 21
@@ -52,7 +52,6 @@ static struct {
52 { "HP NC370i Multifunction Gigabit Server Adapter" }, 52 { "HP NC370i Multifunction Gigabit Server Adapter" },
53 { "Broadcom NetXtreme II BCM5706 1000Base-SX" }, 53 { "Broadcom NetXtreme II BCM5706 1000Base-SX" },
54 { "HP NC370F Multifunction Gigabit Server Adapter" }, 54 { "HP NC370F Multifunction Gigabit Server Adapter" },
55 { 0 },
56 }; 55 };
57 56
58static struct pci_device_id bnx2_pci_tbl[] = { 57static struct pci_device_id bnx2_pci_tbl[] = {
@@ -108,6 +107,15 @@ static struct flash_spec flash_table[] =
108 107
109MODULE_DEVICE_TABLE(pci, bnx2_pci_tbl); 108MODULE_DEVICE_TABLE(pci, bnx2_pci_tbl);
110 109
110static inline u32 bnx2_tx_avail(struct bnx2 *bp)
111{
112 u32 diff = TX_RING_IDX(bp->tx_prod) - TX_RING_IDX(bp->tx_cons);
113
114 if (diff > MAX_TX_DESC_CNT)
115 diff = (diff & MAX_TX_DESC_CNT) - 1;
116 return (bp->tx_ring_size - diff);
117}
118
111static u32 119static u32
112bnx2_reg_rd_ind(struct bnx2 *bp, u32 offset) 120bnx2_reg_rd_ind(struct bnx2 *bp, u32 offset)
113{ 121{
@@ -807,7 +815,19 @@ bnx2_setup_serdes_phy(struct bnx2 *bp)
807 bnx2_write_phy(bp, MII_ADVERTISE, new_adv); 815 bnx2_write_phy(bp, MII_ADVERTISE, new_adv);
808 bnx2_write_phy(bp, MII_BMCR, bmcr | BMCR_ANRESTART | 816 bnx2_write_phy(bp, MII_BMCR, bmcr | BMCR_ANRESTART |
809 BMCR_ANENABLE); 817 BMCR_ANENABLE);
810 bp->serdes_an_pending = SERDES_AN_TIMEOUT / bp->timer_interval; 818 if (CHIP_NUM(bp) == CHIP_NUM_5706) {
819 /* Speed up link-up time when the link partner
820 * does not autonegotiate which is very common
821 * in blade servers. Some blade servers use
822 * IPMI for kerboard input and it's important
823 * to minimize link disruptions. Autoneg. involves
824 * exchanging base pages plus 3 next pages and
825 * normally completes in about 120 msec.
826 */
827 bp->current_interval = SERDES_AN_TIMEOUT;
828 bp->serdes_an_pending = 1;
829 mod_timer(&bp->timer, jiffies + bp->current_interval);
830 }
811 } 831 }
812 832
813 return 0; 833 return 0;
@@ -1327,22 +1347,17 @@ bnx2_tx_int(struct bnx2 *bp)
1327 } 1347 }
1328 } 1348 }
1329 1349
1330 atomic_add(tx_free_bd, &bp->tx_avail_bd); 1350 bp->tx_cons = sw_cons;
1331 1351
1332 if (unlikely(netif_queue_stopped(bp->dev))) { 1352 if (unlikely(netif_queue_stopped(bp->dev))) {
1333 unsigned long flags; 1353 spin_lock(&bp->tx_lock);
1334
1335 spin_lock_irqsave(&bp->tx_lock, flags);
1336 if ((netif_queue_stopped(bp->dev)) && 1354 if ((netif_queue_stopped(bp->dev)) &&
1337 (atomic_read(&bp->tx_avail_bd) > MAX_SKB_FRAGS)) { 1355 (bnx2_tx_avail(bp) > MAX_SKB_FRAGS)) {
1338 1356
1339 netif_wake_queue(bp->dev); 1357 netif_wake_queue(bp->dev);
1340 } 1358 }
1341 spin_unlock_irqrestore(&bp->tx_lock, flags); 1359 spin_unlock(&bp->tx_lock);
1342 } 1360 }
1343
1344 bp->tx_cons = sw_cons;
1345
1346} 1361}
1347 1362
1348static inline void 1363static inline void
@@ -1523,15 +1538,12 @@ bnx2_msi(int irq, void *dev_instance, struct pt_regs *regs)
1523 BNX2_PCICFG_INT_ACK_CMD_MASK_INT); 1538 BNX2_PCICFG_INT_ACK_CMD_MASK_INT);
1524 1539
1525 /* Return here if interrupt is disabled. */ 1540 /* Return here if interrupt is disabled. */
1526 if (unlikely(atomic_read(&bp->intr_sem) != 0)) { 1541 if (unlikely(atomic_read(&bp->intr_sem) != 0))
1527 return IRQ_RETVAL(1); 1542 return IRQ_HANDLED;
1528 }
1529 1543
1530 if (netif_rx_schedule_prep(dev)) { 1544 netif_rx_schedule(dev);
1531 __netif_rx_schedule(dev);
1532 }
1533 1545
1534 return IRQ_RETVAL(1); 1546 return IRQ_HANDLED;
1535} 1547}
1536 1548
1537static irqreturn_t 1549static irqreturn_t
@@ -1549,22 +1561,19 @@ bnx2_interrupt(int irq, void *dev_instance, struct pt_regs *regs)
1549 if ((bp->status_blk->status_idx == bp->last_status_idx) || 1561 if ((bp->status_blk->status_idx == bp->last_status_idx) ||
1550 (REG_RD(bp, BNX2_PCICFG_MISC_STATUS) & 1562 (REG_RD(bp, BNX2_PCICFG_MISC_STATUS) &
1551 BNX2_PCICFG_MISC_STATUS_INTA_VALUE)) 1563 BNX2_PCICFG_MISC_STATUS_INTA_VALUE))
1552 return IRQ_RETVAL(0); 1564 return IRQ_NONE;
1553 1565
1554 REG_WR(bp, BNX2_PCICFG_INT_ACK_CMD, 1566 REG_WR(bp, BNX2_PCICFG_INT_ACK_CMD,
1555 BNX2_PCICFG_INT_ACK_CMD_USE_INT_HC_PARAM | 1567 BNX2_PCICFG_INT_ACK_CMD_USE_INT_HC_PARAM |
1556 BNX2_PCICFG_INT_ACK_CMD_MASK_INT); 1568 BNX2_PCICFG_INT_ACK_CMD_MASK_INT);
1557 1569
1558 /* Return here if interrupt is shared and is disabled. */ 1570 /* Return here if interrupt is shared and is disabled. */
1559 if (unlikely(atomic_read(&bp->intr_sem) != 0)) { 1571 if (unlikely(atomic_read(&bp->intr_sem) != 0))
1560 return IRQ_RETVAL(1); 1572 return IRQ_HANDLED;
1561 }
1562 1573
1563 if (netif_rx_schedule_prep(dev)) { 1574 netif_rx_schedule(dev);
1564 __netif_rx_schedule(dev);
1565 }
1566 1575
1567 return IRQ_RETVAL(1); 1576 return IRQ_HANDLED;
1568} 1577}
1569 1578
1570static int 1579static int
@@ -1581,11 +1590,9 @@ bnx2_poll(struct net_device *dev, int *budget)
1581 (bp->status_blk->status_attn_bits_ack & 1590 (bp->status_blk->status_attn_bits_ack &
1582 STATUS_ATTN_BITS_LINK_STATE)) { 1591 STATUS_ATTN_BITS_LINK_STATE)) {
1583 1592
1584 unsigned long flags; 1593 spin_lock(&bp->phy_lock);
1585
1586 spin_lock_irqsave(&bp->phy_lock, flags);
1587 bnx2_phy_int(bp); 1594 bnx2_phy_int(bp);
1588 spin_unlock_irqrestore(&bp->phy_lock, flags); 1595 spin_unlock(&bp->phy_lock);
1589 } 1596 }
1590 1597
1591 if (bp->status_blk->status_tx_quick_consumer_index0 != bp->tx_cons) { 1598 if (bp->status_blk->status_tx_quick_consumer_index0 != bp->tx_cons) {
@@ -1628,9 +1635,8 @@ bnx2_set_rx_mode(struct net_device *dev)
1628 struct bnx2 *bp = dev->priv; 1635 struct bnx2 *bp = dev->priv;
1629 u32 rx_mode, sort_mode; 1636 u32 rx_mode, sort_mode;
1630 int i; 1637 int i;
1631 unsigned long flags;
1632 1638
1633 spin_lock_irqsave(&bp->phy_lock, flags); 1639 spin_lock_bh(&bp->phy_lock);
1634 1640
1635 rx_mode = bp->rx_mode & ~(BNX2_EMAC_RX_MODE_PROMISCUOUS | 1641 rx_mode = bp->rx_mode & ~(BNX2_EMAC_RX_MODE_PROMISCUOUS |
1636 BNX2_EMAC_RX_MODE_KEEP_VLAN_TAG); 1642 BNX2_EMAC_RX_MODE_KEEP_VLAN_TAG);
@@ -1691,7 +1697,7 @@ bnx2_set_rx_mode(struct net_device *dev)
1691 REG_WR(bp, BNX2_RPM_SORT_USER0, sort_mode); 1697 REG_WR(bp, BNX2_RPM_SORT_USER0, sort_mode);
1692 REG_WR(bp, BNX2_RPM_SORT_USER0, sort_mode | BNX2_RPM_SORT_USER0_ENA); 1698 REG_WR(bp, BNX2_RPM_SORT_USER0, sort_mode | BNX2_RPM_SORT_USER0_ENA);
1693 1699
1694 spin_unlock_irqrestore(&bp->phy_lock, flags); 1700 spin_unlock_bh(&bp->phy_lock);
1695} 1701}
1696 1702
1697static void 1703static void
@@ -2960,7 +2966,6 @@ bnx2_init_tx_ring(struct bnx2 *bp)
2960 bp->tx_prod = 0; 2966 bp->tx_prod = 0;
2961 bp->tx_cons = 0; 2967 bp->tx_cons = 0;
2962 bp->tx_prod_bseq = 0; 2968 bp->tx_prod_bseq = 0;
2963 atomic_set(&bp->tx_avail_bd, bp->tx_ring_size);
2964 2969
2965 val = BNX2_L2CTX_TYPE_TYPE_L2; 2970 val = BNX2_L2CTX_TYPE_TYPE_L2;
2966 val |= BNX2_L2CTX_TYPE_SIZE_L2; 2971 val |= BNX2_L2CTX_TYPE_SIZE_L2;
@@ -3507,11 +3512,11 @@ bnx2_test_registers(struct bnx2 *bp)
3507 rw_mask = reg_tbl[i].rw_mask; 3512 rw_mask = reg_tbl[i].rw_mask;
3508 ro_mask = reg_tbl[i].ro_mask; 3513 ro_mask = reg_tbl[i].ro_mask;
3509 3514
3510 save_val = readl((u8 *) bp->regview + offset); 3515 save_val = readl(bp->regview + offset);
3511 3516
3512 writel(0, (u8 *) bp->regview + offset); 3517 writel(0, bp->regview + offset);
3513 3518
3514 val = readl((u8 *) bp->regview + offset); 3519 val = readl(bp->regview + offset);
3515 if ((val & rw_mask) != 0) { 3520 if ((val & rw_mask) != 0) {
3516 goto reg_test_err; 3521 goto reg_test_err;
3517 } 3522 }
@@ -3520,9 +3525,9 @@ bnx2_test_registers(struct bnx2 *bp)
3520 goto reg_test_err; 3525 goto reg_test_err;
3521 } 3526 }
3522 3527
3523 writel(0xffffffff, (u8 *) bp->regview + offset); 3528 writel(0xffffffff, bp->regview + offset);
3524 3529
3525 val = readl((u8 *) bp->regview + offset); 3530 val = readl(bp->regview + offset);
3526 if ((val & rw_mask) != rw_mask) { 3531 if ((val & rw_mask) != rw_mask) {
3527 goto reg_test_err; 3532 goto reg_test_err;
3528 } 3533 }
@@ -3531,11 +3536,11 @@ bnx2_test_registers(struct bnx2 *bp)
3531 goto reg_test_err; 3536 goto reg_test_err;
3532 } 3537 }
3533 3538
3534 writel(save_val, (u8 *) bp->regview + offset); 3539 writel(save_val, bp->regview + offset);
3535 continue; 3540 continue;
3536 3541
3537reg_test_err: 3542reg_test_err:
3538 writel(save_val, (u8 *) bp->regview + offset); 3543 writel(save_val, bp->regview + offset);
3539 ret = -ENODEV; 3544 ret = -ENODEV;
3540 break; 3545 break;
3541 } 3546 }
@@ -3752,10 +3757,10 @@ bnx2_test_link(struct bnx2 *bp)
3752{ 3757{
3753 u32 bmsr; 3758 u32 bmsr;
3754 3759
3755 spin_lock_irq(&bp->phy_lock); 3760 spin_lock_bh(&bp->phy_lock);
3756 bnx2_read_phy(bp, MII_BMSR, &bmsr); 3761 bnx2_read_phy(bp, MII_BMSR, &bmsr);
3757 bnx2_read_phy(bp, MII_BMSR, &bmsr); 3762 bnx2_read_phy(bp, MII_BMSR, &bmsr);
3758 spin_unlock_irq(&bp->phy_lock); 3763 spin_unlock_bh(&bp->phy_lock);
3759 3764
3760 if (bmsr & BMSR_LSTATUS) { 3765 if (bmsr & BMSR_LSTATUS) {
3761 return 0; 3766 return 0;
@@ -3801,6 +3806,9 @@ bnx2_timer(unsigned long data)
3801 struct bnx2 *bp = (struct bnx2 *) data; 3806 struct bnx2 *bp = (struct bnx2 *) data;
3802 u32 msg; 3807 u32 msg;
3803 3808
3809 if (!netif_running(bp->dev))
3810 return;
3811
3804 if (atomic_read(&bp->intr_sem) != 0) 3812 if (atomic_read(&bp->intr_sem) != 0)
3805 goto bnx2_restart_timer; 3813 goto bnx2_restart_timer;
3806 3814
@@ -3809,15 +3817,16 @@ bnx2_timer(unsigned long data)
3809 3817
3810 if ((bp->phy_flags & PHY_SERDES_FLAG) && 3818 if ((bp->phy_flags & PHY_SERDES_FLAG) &&
3811 (CHIP_NUM(bp) == CHIP_NUM_5706)) { 3819 (CHIP_NUM(bp) == CHIP_NUM_5706)) {
3812 unsigned long flags;
3813 3820
3814 spin_lock_irqsave(&bp->phy_lock, flags); 3821 spin_lock(&bp->phy_lock);
3815 if (bp->serdes_an_pending) { 3822 if (bp->serdes_an_pending) {
3816 bp->serdes_an_pending--; 3823 bp->serdes_an_pending--;
3817 } 3824 }
3818 else if ((bp->link_up == 0) && (bp->autoneg & AUTONEG_SPEED)) { 3825 else if ((bp->link_up == 0) && (bp->autoneg & AUTONEG_SPEED)) {
3819 u32 bmcr; 3826 u32 bmcr;
3820 3827
3828 bp->current_interval = bp->timer_interval;
3829
3821 bnx2_read_phy(bp, MII_BMCR, &bmcr); 3830 bnx2_read_phy(bp, MII_BMCR, &bmcr);
3822 3831
3823 if (bmcr & BMCR_ANENABLE) { 3832 if (bmcr & BMCR_ANENABLE) {
@@ -3860,14 +3869,14 @@ bnx2_timer(unsigned long data)
3860 3869
3861 } 3870 }
3862 } 3871 }
3872 else
3873 bp->current_interval = bp->timer_interval;
3863 3874
3864 spin_unlock_irqrestore(&bp->phy_lock, flags); 3875 spin_unlock(&bp->phy_lock);
3865 } 3876 }
3866 3877
3867bnx2_restart_timer: 3878bnx2_restart_timer:
3868 bp->timer.expires = RUN_AT(bp->timer_interval); 3879 mod_timer(&bp->timer, jiffies + bp->current_interval);
3869
3870 add_timer(&bp->timer);
3871} 3880}
3872 3881
3873/* Called with rtnl_lock */ 3882/* Called with rtnl_lock */
@@ -3920,12 +3929,7 @@ bnx2_open(struct net_device *dev)
3920 return rc; 3929 return rc;
3921 } 3930 }
3922 3931
3923 init_timer(&bp->timer); 3932 mod_timer(&bp->timer, jiffies + bp->current_interval);
3924
3925 bp->timer.expires = RUN_AT(bp->timer_interval);
3926 bp->timer.data = (unsigned long) bp;
3927 bp->timer.function = bnx2_timer;
3928 add_timer(&bp->timer);
3929 3933
3930 atomic_set(&bp->intr_sem, 0); 3934 atomic_set(&bp->intr_sem, 0);
3931 3935
@@ -3976,12 +3980,17 @@ bnx2_reset_task(void *data)
3976{ 3980{
3977 struct bnx2 *bp = data; 3981 struct bnx2 *bp = data;
3978 3982
3983 if (!netif_running(bp->dev))
3984 return;
3985
3986 bp->in_reset_task = 1;
3979 bnx2_netif_stop(bp); 3987 bnx2_netif_stop(bp);
3980 3988
3981 bnx2_init_nic(bp); 3989 bnx2_init_nic(bp);
3982 3990
3983 atomic_set(&bp->intr_sem, 1); 3991 atomic_set(&bp->intr_sem, 1);
3984 bnx2_netif_start(bp); 3992 bnx2_netif_start(bp);
3993 bp->in_reset_task = 0;
3985} 3994}
3986 3995
3987static void 3996static void
@@ -4041,9 +4050,7 @@ bnx2_start_xmit(struct sk_buff *skb, struct net_device *dev)
4041 u16 prod, ring_prod; 4050 u16 prod, ring_prod;
4042 int i; 4051 int i;
4043 4052
4044 if (unlikely(atomic_read(&bp->tx_avail_bd) < 4053 if (unlikely(bnx2_tx_avail(bp) < (skb_shinfo(skb)->nr_frags + 1))) {
4045 (skb_shinfo(skb)->nr_frags + 1))) {
4046
4047 netif_stop_queue(dev); 4054 netif_stop_queue(dev);
4048 printk(KERN_ERR PFX "%s: BUG! Tx ring full when queue awake!\n", 4055 printk(KERN_ERR PFX "%s: BUG! Tx ring full when queue awake!\n",
4049 dev->name); 4056 dev->name);
@@ -4140,8 +4147,6 @@ bnx2_start_xmit(struct sk_buff *skb, struct net_device *dev)
4140 prod = NEXT_TX_BD(prod); 4147 prod = NEXT_TX_BD(prod);
4141 bp->tx_prod_bseq += skb->len; 4148 bp->tx_prod_bseq += skb->len;
4142 4149
4143 atomic_sub(last_frag + 1, &bp->tx_avail_bd);
4144
4145 REG_WR16(bp, MB_TX_CID_ADDR + BNX2_L2CTX_TX_HOST_BIDX, prod); 4150 REG_WR16(bp, MB_TX_CID_ADDR + BNX2_L2CTX_TX_HOST_BIDX, prod);
4146 REG_WR(bp, MB_TX_CID_ADDR + BNX2_L2CTX_TX_HOST_BSEQ, bp->tx_prod_bseq); 4151 REG_WR(bp, MB_TX_CID_ADDR + BNX2_L2CTX_TX_HOST_BSEQ, bp->tx_prod_bseq);
4147 4152
@@ -4150,17 +4155,13 @@ bnx2_start_xmit(struct sk_buff *skb, struct net_device *dev)
4150 bp->tx_prod = prod; 4155 bp->tx_prod = prod;
4151 dev->trans_start = jiffies; 4156 dev->trans_start = jiffies;
4152 4157
4153 if (unlikely(atomic_read(&bp->tx_avail_bd) <= MAX_SKB_FRAGS)) { 4158 if (unlikely(bnx2_tx_avail(bp) <= MAX_SKB_FRAGS)) {
4154 unsigned long flags; 4159 spin_lock(&bp->tx_lock);
4155 4160 netif_stop_queue(dev);
4156 spin_lock_irqsave(&bp->tx_lock, flags); 4161
4157 if (atomic_read(&bp->tx_avail_bd) <= MAX_SKB_FRAGS) { 4162 if (bnx2_tx_avail(bp) > MAX_SKB_FRAGS)
4158 netif_stop_queue(dev); 4163 netif_wake_queue(dev);
4159 4164 spin_unlock(&bp->tx_lock);
4160 if (atomic_read(&bp->tx_avail_bd) > MAX_SKB_FRAGS)
4161 netif_wake_queue(dev);
4162 }
4163 spin_unlock_irqrestore(&bp->tx_lock, flags);
4164 } 4165 }
4165 4166
4166 return NETDEV_TX_OK; 4167 return NETDEV_TX_OK;
@@ -4173,7 +4174,13 @@ bnx2_close(struct net_device *dev)
4173 struct bnx2 *bp = dev->priv; 4174 struct bnx2 *bp = dev->priv;
4174 u32 reset_code; 4175 u32 reset_code;
4175 4176
4176 flush_scheduled_work(); 4177 /* Calling flush_scheduled_work() may deadlock because
4178 * linkwatch_event() may be on the workqueue and it will try to get
4179 * the rtnl_lock which we are holding.
4180 */
4181 while (bp->in_reset_task)
4182 msleep(1);
4183
4177 bnx2_netif_stop(bp); 4184 bnx2_netif_stop(bp);
4178 del_timer_sync(&bp->timer); 4185 del_timer_sync(&bp->timer);
4179 if (bp->wol) 4186 if (bp->wol)
@@ -4390,11 +4397,11 @@ bnx2_set_settings(struct net_device *dev, struct ethtool_cmd *cmd)
4390 bp->req_line_speed = req_line_speed; 4397 bp->req_line_speed = req_line_speed;
4391 bp->req_duplex = req_duplex; 4398 bp->req_duplex = req_duplex;
4392 4399
4393 spin_lock_irq(&bp->phy_lock); 4400 spin_lock_bh(&bp->phy_lock);
4394 4401
4395 bnx2_setup_phy(bp); 4402 bnx2_setup_phy(bp);
4396 4403
4397 spin_unlock_irq(&bp->phy_lock); 4404 spin_unlock_bh(&bp->phy_lock);
4398 4405
4399 return 0; 4406 return 0;
4400} 4407}
@@ -4464,19 +4471,20 @@ bnx2_nway_reset(struct net_device *dev)
4464 return -EINVAL; 4471 return -EINVAL;
4465 } 4472 }
4466 4473
4467 spin_lock_irq(&bp->phy_lock); 4474 spin_lock_bh(&bp->phy_lock);
4468 4475
4469 /* Force a link down visible on the other side */ 4476 /* Force a link down visible on the other side */
4470 if (bp->phy_flags & PHY_SERDES_FLAG) { 4477 if (bp->phy_flags & PHY_SERDES_FLAG) {
4471 bnx2_write_phy(bp, MII_BMCR, BMCR_LOOPBACK); 4478 bnx2_write_phy(bp, MII_BMCR, BMCR_LOOPBACK);
4472 spin_unlock_irq(&bp->phy_lock); 4479 spin_unlock_bh(&bp->phy_lock);
4473 4480
4474 msleep(20); 4481 msleep(20);
4475 4482
4476 spin_lock_irq(&bp->phy_lock); 4483 spin_lock_bh(&bp->phy_lock);
4477 if (CHIP_NUM(bp) == CHIP_NUM_5706) { 4484 if (CHIP_NUM(bp) == CHIP_NUM_5706) {
4478 bp->serdes_an_pending = SERDES_AN_TIMEOUT / 4485 bp->current_interval = SERDES_AN_TIMEOUT;
4479 bp->timer_interval; 4486 bp->serdes_an_pending = 1;
4487 mod_timer(&bp->timer, jiffies + bp->current_interval);
4480 } 4488 }
4481 } 4489 }
4482 4490
@@ -4484,7 +4492,7 @@ bnx2_nway_reset(struct net_device *dev)
4484 bmcr &= ~BMCR_LOOPBACK; 4492 bmcr &= ~BMCR_LOOPBACK;
4485 bnx2_write_phy(bp, MII_BMCR, bmcr | BMCR_ANRESTART | BMCR_ANENABLE); 4493 bnx2_write_phy(bp, MII_BMCR, bmcr | BMCR_ANRESTART | BMCR_ANENABLE);
4486 4494
4487 spin_unlock_irq(&bp->phy_lock); 4495 spin_unlock_bh(&bp->phy_lock);
4488 4496
4489 return 0; 4497 return 0;
4490} 4498}
@@ -4670,11 +4678,11 @@ bnx2_set_pauseparam(struct net_device *dev, struct ethtool_pauseparam *epause)
4670 bp->autoneg &= ~AUTONEG_FLOW_CTRL; 4678 bp->autoneg &= ~AUTONEG_FLOW_CTRL;
4671 } 4679 }
4672 4680
4673 spin_lock_irq(&bp->phy_lock); 4681 spin_lock_bh(&bp->phy_lock);
4674 4682
4675 bnx2_setup_phy(bp); 4683 bnx2_setup_phy(bp);
4676 4684
4677 spin_unlock_irq(&bp->phy_lock); 4685 spin_unlock_bh(&bp->phy_lock);
4678 4686
4679 return 0; 4687 return 0;
4680} 4688}
@@ -4698,7 +4706,7 @@ bnx2_set_rx_csum(struct net_device *dev, u32 data)
4698 4706
4699#define BNX2_NUM_STATS 45 4707#define BNX2_NUM_STATS 45
4700 4708
4701struct { 4709static struct {
4702 char string[ETH_GSTRING_LEN]; 4710 char string[ETH_GSTRING_LEN];
4703} bnx2_stats_str_arr[BNX2_NUM_STATS] = { 4711} bnx2_stats_str_arr[BNX2_NUM_STATS] = {
4704 { "rx_bytes" }, 4712 { "rx_bytes" },
@@ -4750,7 +4758,7 @@ struct {
4750 4758
4751#define STATS_OFFSET32(offset_name) (offsetof(struct statistics_block, offset_name) / 4) 4759#define STATS_OFFSET32(offset_name) (offsetof(struct statistics_block, offset_name) / 4)
4752 4760
4753unsigned long bnx2_stats_offset_arr[BNX2_NUM_STATS] = { 4761static unsigned long bnx2_stats_offset_arr[BNX2_NUM_STATS] = {
4754 STATS_OFFSET32(stat_IfHCInOctets_hi), 4762 STATS_OFFSET32(stat_IfHCInOctets_hi),
4755 STATS_OFFSET32(stat_IfHCInBadOctets_hi), 4763 STATS_OFFSET32(stat_IfHCInBadOctets_hi),
4756 STATS_OFFSET32(stat_IfHCOutOctets_hi), 4764 STATS_OFFSET32(stat_IfHCOutOctets_hi),
@@ -4801,7 +4809,7 @@ unsigned long bnx2_stats_offset_arr[BNX2_NUM_STATS] = {
4801/* stat_IfHCInBadOctets and stat_Dot3StatsCarrierSenseErrors are 4809/* stat_IfHCInBadOctets and stat_Dot3StatsCarrierSenseErrors are
4802 * skipped because of errata. 4810 * skipped because of errata.
4803 */ 4811 */
4804u8 bnx2_5706_stats_len_arr[BNX2_NUM_STATS] = { 4812static u8 bnx2_5706_stats_len_arr[BNX2_NUM_STATS] = {
4805 8,0,8,8,8,8,8,8,8,8, 4813 8,0,8,8,8,8,8,8,8,8,
4806 4,0,4,4,4,4,4,4,4,4, 4814 4,0,4,4,4,4,4,4,4,4,
4807 4,4,4,4,4,4,4,4,4,4, 4815 4,4,4,4,4,4,4,4,4,4,
@@ -4811,7 +4819,7 @@ u8 bnx2_5706_stats_len_arr[BNX2_NUM_STATS] = {
4811 4819
4812#define BNX2_NUM_TESTS 6 4820#define BNX2_NUM_TESTS 6
4813 4821
4814struct { 4822static struct {
4815 char string[ETH_GSTRING_LEN]; 4823 char string[ETH_GSTRING_LEN];
4816} bnx2_tests_str_arr[BNX2_NUM_TESTS] = { 4824} bnx2_tests_str_arr[BNX2_NUM_TESTS] = {
4817 { "register_test (offline)" }, 4825 { "register_test (offline)" },
@@ -4910,7 +4918,7 @@ bnx2_get_ethtool_stats(struct net_device *dev,
4910 struct bnx2 *bp = dev->priv; 4918 struct bnx2 *bp = dev->priv;
4911 int i; 4919 int i;
4912 u32 *hw_stats = (u32 *) bp->stats_blk; 4920 u32 *hw_stats = (u32 *) bp->stats_blk;
4913 u8 *stats_len_arr = 0; 4921 u8 *stats_len_arr = NULL;
4914 4922
4915 if (hw_stats == NULL) { 4923 if (hw_stats == NULL) {
4916 memset(buf, 0, sizeof(u64) * BNX2_NUM_STATS); 4924 memset(buf, 0, sizeof(u64) * BNX2_NUM_STATS);
@@ -5012,7 +5020,7 @@ static struct ethtool_ops bnx2_ethtool_ops = {
5012static int 5020static int
5013bnx2_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd) 5021bnx2_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd)
5014{ 5022{
5015 struct mii_ioctl_data *data = (struct mii_ioctl_data *)&ifr->ifr_data; 5023 struct mii_ioctl_data *data = if_mii(ifr);
5016 struct bnx2 *bp = dev->priv; 5024 struct bnx2 *bp = dev->priv;
5017 int err; 5025 int err;
5018 5026
@@ -5024,9 +5032,9 @@ bnx2_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd)
5024 case SIOCGMIIREG: { 5032 case SIOCGMIIREG: {
5025 u32 mii_regval; 5033 u32 mii_regval;
5026 5034
5027 spin_lock_irq(&bp->phy_lock); 5035 spin_lock_bh(&bp->phy_lock);
5028 err = bnx2_read_phy(bp, data->reg_num & 0x1f, &mii_regval); 5036 err = bnx2_read_phy(bp, data->reg_num & 0x1f, &mii_regval);
5029 spin_unlock_irq(&bp->phy_lock); 5037 spin_unlock_bh(&bp->phy_lock);
5030 5038
5031 data->val_out = mii_regval; 5039 data->val_out = mii_regval;
5032 5040
@@ -5037,9 +5045,9 @@ bnx2_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd)
5037 if (!capable(CAP_NET_ADMIN)) 5045 if (!capable(CAP_NET_ADMIN))
5038 return -EPERM; 5046 return -EPERM;
5039 5047
5040 spin_lock_irq(&bp->phy_lock); 5048 spin_lock_bh(&bp->phy_lock);
5041 err = bnx2_write_phy(bp, data->reg_num & 0x1f, data->val_in); 5049 err = bnx2_write_phy(bp, data->reg_num & 0x1f, data->val_in);
5042 spin_unlock_irq(&bp->phy_lock); 5050 spin_unlock_bh(&bp->phy_lock);
5043 5051
5044 return err; 5052 return err;
5045 5053
@@ -5057,6 +5065,9 @@ bnx2_change_mac_addr(struct net_device *dev, void *p)
5057 struct sockaddr *addr = p; 5065 struct sockaddr *addr = p;
5058 struct bnx2 *bp = dev->priv; 5066 struct bnx2 *bp = dev->priv;
5059 5067
5068 if (!is_valid_ether_addr(addr->sa_data))
5069 return -EINVAL;
5070
5060 memcpy(dev->dev_addr, addr->sa_data, dev->addr_len); 5071 memcpy(dev->dev_addr, addr->sa_data, dev->addr_len);
5061 if (netif_running(dev)) 5072 if (netif_running(dev))
5062 bnx2_set_mac_addr(bp); 5073 bnx2_set_mac_addr(bp);
@@ -5305,6 +5316,7 @@ bnx2_init_board(struct pci_dev *pdev, struct net_device *dev)
5305 bp->stats_ticks = 1000000 & 0xffff00; 5316 bp->stats_ticks = 1000000 & 0xffff00;
5306 5317
5307 bp->timer_interval = HZ; 5318 bp->timer_interval = HZ;
5319 bp->current_interval = HZ;
5308 5320
5309 /* Disable WOL support if we are running on a SERDES chip. */ 5321 /* Disable WOL support if we are running on a SERDES chip. */
5310 if (CHIP_BOND_ID(bp) & CHIP_BOND_ID_SERDES_BIT) { 5322 if (CHIP_BOND_ID(bp) & CHIP_BOND_ID_SERDES_BIT) {
@@ -5328,6 +5340,15 @@ bnx2_init_board(struct pci_dev *pdev, struct net_device *dev)
5328 bp->req_line_speed = 0; 5340 bp->req_line_speed = 0;
5329 if (bp->phy_flags & PHY_SERDES_FLAG) { 5341 if (bp->phy_flags & PHY_SERDES_FLAG) {
5330 bp->advertising = ETHTOOL_ALL_FIBRE_SPEED | ADVERTISED_Autoneg; 5342 bp->advertising = ETHTOOL_ALL_FIBRE_SPEED | ADVERTISED_Autoneg;
5343
5344 reg = REG_RD_IND(bp, HOST_VIEW_SHMEM_BASE +
5345 BNX2_PORT_HW_CFG_CONFIG);
5346 reg &= BNX2_PORT_HW_CFG_CFG_DFLT_LINK_MASK;
5347 if (reg == BNX2_PORT_HW_CFG_CFG_DFLT_LINK_1G) {
5348 bp->autoneg = 0;
5349 bp->req_line_speed = bp->line_speed = SPEED_1000;
5350 bp->req_duplex = DUPLEX_FULL;
5351 }
5331 } 5352 }
5332 else { 5353 else {
5333 bp->advertising = ETHTOOL_ALL_COPPER_SPEED | ADVERTISED_Autoneg; 5354 bp->advertising = ETHTOOL_ALL_COPPER_SPEED | ADVERTISED_Autoneg;
@@ -5335,11 +5356,17 @@ bnx2_init_board(struct pci_dev *pdev, struct net_device *dev)
5335 5356
5336 bp->req_flow_ctrl = FLOW_CTRL_RX | FLOW_CTRL_TX; 5357 bp->req_flow_ctrl = FLOW_CTRL_RX | FLOW_CTRL_TX;
5337 5358
5359 init_timer(&bp->timer);
5360 bp->timer.expires = RUN_AT(bp->timer_interval);
5361 bp->timer.data = (unsigned long) bp;
5362 bp->timer.function = bnx2_timer;
5363
5338 return 0; 5364 return 0;
5339 5365
5340err_out_unmap: 5366err_out_unmap:
5341 if (bp->regview) { 5367 if (bp->regview) {
5342 iounmap(bp->regview); 5368 iounmap(bp->regview);
5369 bp->regview = NULL;
5343 } 5370 }
5344 5371
5345err_out_release: 5372err_out_release:
@@ -5454,6 +5481,8 @@ bnx2_remove_one(struct pci_dev *pdev)
5454 struct net_device *dev = pci_get_drvdata(pdev); 5481 struct net_device *dev = pci_get_drvdata(pdev);
5455 struct bnx2 *bp = dev->priv; 5482 struct bnx2 *bp = dev->priv;
5456 5483
5484 flush_scheduled_work();
5485
5457 unregister_netdev(dev); 5486 unregister_netdev(dev);
5458 5487
5459 if (bp->regview) 5488 if (bp->regview)
@@ -5505,12 +5534,12 @@ bnx2_resume(struct pci_dev *pdev)
5505} 5534}
5506 5535
5507static struct pci_driver bnx2_pci_driver = { 5536static struct pci_driver bnx2_pci_driver = {
5508 name: DRV_MODULE_NAME, 5537 .name = DRV_MODULE_NAME,
5509 id_table: bnx2_pci_tbl, 5538 .id_table = bnx2_pci_tbl,
5510 probe: bnx2_init_one, 5539 .probe = bnx2_init_one,
5511 remove: __devexit_p(bnx2_remove_one), 5540 .remove = __devexit_p(bnx2_remove_one),
5512 suspend: bnx2_suspend, 5541 .suspend = bnx2_suspend,
5513 resume: bnx2_resume, 5542 .resume = bnx2_resume,
5514}; 5543};
5515 5544
5516static int __init bnx2_init(void) 5545static int __init bnx2_init(void)
diff --git a/drivers/net/bnx2.h b/drivers/net/bnx2.h
index 8214a2853d0d..9ad3f5740cd8 100644
--- a/drivers/net/bnx2.h
+++ b/drivers/net/bnx2.h
@@ -3841,12 +3841,12 @@ struct bnx2 {
3841 struct status_block *status_blk; 3841 struct status_block *status_blk;
3842 u32 last_status_idx; 3842 u32 last_status_idx;
3843 3843
3844 atomic_t tx_avail_bd;
3845 struct tx_bd *tx_desc_ring; 3844 struct tx_bd *tx_desc_ring;
3846 struct sw_bd *tx_buf_ring; 3845 struct sw_bd *tx_buf_ring;
3847 u32 tx_prod_bseq; 3846 u32 tx_prod_bseq;
3848 u16 tx_prod; 3847 u16 tx_prod;
3849 u16 tx_cons; 3848 u16 tx_cons;
3849 int tx_ring_size;
3850 3850
3851#ifdef BCM_VLAN 3851#ifdef BCM_VLAN
3852 struct vlan_group *vlgrp; 3852 struct vlan_group *vlgrp;
@@ -3872,8 +3872,10 @@ struct bnx2 {
3872 char *name; 3872 char *name;
3873 3873
3874 int timer_interval; 3874 int timer_interval;
3875 int current_interval;
3875 struct timer_list timer; 3876 struct timer_list timer;
3876 struct work_struct reset_task; 3877 struct work_struct reset_task;
3878 int in_reset_task;
3877 3879
3878 /* Used to synchronize phy accesses. */ 3880 /* Used to synchronize phy accesses. */
3879 spinlock_t phy_lock; 3881 spinlock_t phy_lock;
@@ -3927,7 +3929,6 @@ struct bnx2 {
3927 u16 fw_wr_seq; 3929 u16 fw_wr_seq;
3928 u16 fw_drv_pulse_wr_seq; 3930 u16 fw_drv_pulse_wr_seq;
3929 3931
3930 int tx_ring_size;
3931 dma_addr_t tx_desc_mapping; 3932 dma_addr_t tx_desc_mapping;
3932 3933
3933 3934
@@ -3985,7 +3986,7 @@ struct bnx2 {
3985#define PHY_LOOPBACK 2 3986#define PHY_LOOPBACK 2
3986 3987
3987 u8 serdes_an_pending; 3988 u8 serdes_an_pending;
3988#define SERDES_AN_TIMEOUT (2 * HZ) 3989#define SERDES_AN_TIMEOUT (HZ / 3)
3989 3990
3990 u8 mac_addr[8]; 3991 u8 mac_addr[8];
3991 3992
@@ -4171,6 +4172,9 @@ struct fw_info {
4171 4172
4172#define BNX2_PORT_HW_CFG_MAC_LOWER 0x00000054 4173#define BNX2_PORT_HW_CFG_MAC_LOWER 0x00000054
4173#define BNX2_PORT_HW_CFG_CONFIG 0x00000058 4174#define BNX2_PORT_HW_CFG_CONFIG 0x00000058
4175#define BNX2_PORT_HW_CFG_CFG_DFLT_LINK_MASK 0x001f0000
4176#define BNX2_PORT_HW_CFG_CFG_DFLT_LINK_AN 0x00000000
4177#define BNX2_PORT_HW_CFG_CFG_DFLT_LINK_1G 0x00030000
4174 4178
4175#define BNX2_PORT_HW_CFG_IMD_MAC_A_UPPER 0x00000068 4179#define BNX2_PORT_HW_CFG_IMD_MAC_A_UPPER 0x00000068
4176#define BNX2_PORT_HW_CFG_IMD_MAC_A_LOWER 0x0000006c 4180#define BNX2_PORT_HW_CFG_IMD_MAC_A_LOWER 0x0000006c
diff --git a/drivers/net/bonding/bond_3ad.c b/drivers/net/bonding/bond_3ad.c
index a2e8dda5afac..d2f34d5a8083 100644
--- a/drivers/net/bonding/bond_3ad.c
+++ b/drivers/net/bonding/bond_3ad.c
@@ -2419,22 +2419,19 @@ out:
2419 return 0; 2419 return 0;
2420} 2420}
2421 2421
2422int bond_3ad_lacpdu_recv(struct sk_buff *skb, struct net_device *dev, struct packet_type* ptype) 2422int bond_3ad_lacpdu_recv(struct sk_buff *skb, struct net_device *dev, struct packet_type* ptype, struct net_device *orig_dev)
2423{ 2423{
2424 struct bonding *bond = dev->priv; 2424 struct bonding *bond = dev->priv;
2425 struct slave *slave = NULL; 2425 struct slave *slave = NULL;
2426 int ret = NET_RX_DROP; 2426 int ret = NET_RX_DROP;
2427 2427
2428 if (!(dev->flags & IFF_MASTER)) { 2428 if (!(dev->flags & IFF_MASTER))
2429 goto out; 2429 goto out;
2430 }
2431 2430
2432 read_lock(&bond->lock); 2431 read_lock(&bond->lock);
2433 slave = bond_get_slave_by_dev((struct bonding *)dev->priv, 2432 slave = bond_get_slave_by_dev((struct bonding *)dev->priv, orig_dev);
2434 skb->real_dev); 2433 if (!slave)
2435 if (slave == NULL) {
2436 goto out_unlock; 2434 goto out_unlock;
2437 }
2438 2435
2439 bond_3ad_rx_indication((struct lacpdu *) skb->data, slave, skb->len); 2436 bond_3ad_rx_indication((struct lacpdu *) skb->data, slave, skb->len);
2440 2437
diff --git a/drivers/net/bonding/bond_3ad.h b/drivers/net/bonding/bond_3ad.h
index f46823894187..673a30af5660 100644
--- a/drivers/net/bonding/bond_3ad.h
+++ b/drivers/net/bonding/bond_3ad.h
@@ -295,6 +295,6 @@ void bond_3ad_adapter_duplex_changed(struct slave *slave);
295void bond_3ad_handle_link_change(struct slave *slave, char link); 295void bond_3ad_handle_link_change(struct slave *slave, char link);
296int bond_3ad_get_active_agg_info(struct bonding *bond, struct ad_info *ad_info); 296int bond_3ad_get_active_agg_info(struct bonding *bond, struct ad_info *ad_info);
297int bond_3ad_xmit_xor(struct sk_buff *skb, struct net_device *dev); 297int bond_3ad_xmit_xor(struct sk_buff *skb, struct net_device *dev);
298int bond_3ad_lacpdu_recv(struct sk_buff *skb, struct net_device *dev, struct packet_type* ptype); 298int bond_3ad_lacpdu_recv(struct sk_buff *skb, struct net_device *dev, struct packet_type* ptype, struct net_device *orig_dev);
299#endif //__BOND_3AD_H__ 299#endif //__BOND_3AD_H__
300 300
diff --git a/drivers/net/bonding/bond_alb.c b/drivers/net/bonding/bond_alb.c
index 19e829b567d0..f8fce3961197 100644
--- a/drivers/net/bonding/bond_alb.c
+++ b/drivers/net/bonding/bond_alb.c
@@ -354,15 +354,14 @@ static void rlb_update_entry_from_arp(struct bonding *bond, struct arp_pkt *arp)
354 _unlock_rx_hashtbl(bond); 354 _unlock_rx_hashtbl(bond);
355} 355}
356 356
357static int rlb_arp_recv(struct sk_buff *skb, struct net_device *bond_dev, struct packet_type *ptype) 357static int rlb_arp_recv(struct sk_buff *skb, struct net_device *bond_dev, struct packet_type *ptype, struct net_device *orig_dev)
358{ 358{
359 struct bonding *bond = bond_dev->priv; 359 struct bonding *bond = bond_dev->priv;
360 struct arp_pkt *arp = (struct arp_pkt *)skb->data; 360 struct arp_pkt *arp = (struct arp_pkt *)skb->data;
361 int res = NET_RX_DROP; 361 int res = NET_RX_DROP;
362 362
363 if (!(bond_dev->flags & IFF_MASTER)) { 363 if (!(bond_dev->flags & IFF_MASTER))
364 goto out; 364 goto out;
365 }
366 365
367 if (!arp) { 366 if (!arp) {
368 dprintk("Packet has no ARP data\n"); 367 dprintk("Packet has no ARP data\n");
diff --git a/drivers/net/chelsio/Makefile b/drivers/net/chelsio/Makefile
new file mode 100644
index 000000000000..91e927827c43
--- /dev/null
+++ b/drivers/net/chelsio/Makefile
@@ -0,0 +1,11 @@
1#
2# Chelsio 10Gb NIC driver for Linux.
3#
4
5obj-$(CONFIG_CHELSIO_T1) += cxgb.o
6
7EXTRA_CFLAGS += -I$(TOPDIR)/drivers/net/chelsio $(DEBUG_FLAGS)
8
9
10cxgb-objs := cxgb2.o espi.o pm3393.o sge.o subr.o mv88x201x.o
11
diff --git a/drivers/net/chelsio/common.h b/drivers/net/chelsio/common.h
new file mode 100644
index 000000000000..f09348802b46
--- /dev/null
+++ b/drivers/net/chelsio/common.h
@@ -0,0 +1,314 @@
1/*****************************************************************************
2 * *
3 * File: common.h *
4 * $Revision: 1.21 $ *
5 * $Date: 2005/06/22 00:43:25 $ *
6 * Description: *
7 * part of the Chelsio 10Gb Ethernet Driver. *
8 * *
9 * This program is free software; you can redistribute it and/or modify *
10 * it under the terms of the GNU General Public License, version 2, as *
11 * published by the Free Software Foundation. *
12 * *
13 * You should have received a copy of the GNU General Public License along *
14 * with this program; if not, write to the Free Software Foundation, Inc., *
15 * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
16 * *
17 * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED *
18 * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF *
19 * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. *
20 * *
21 * http://www.chelsio.com *
22 * *
23 * Copyright (c) 2003 - 2005 Chelsio Communications, Inc. *
24 * All rights reserved. *
25 * *
26 * Maintainers: maintainers@chelsio.com *
27 * *
28 * Authors: Dimitrios Michailidis <dm@chelsio.com> *
29 * Tina Yang <tainay@chelsio.com> *
30 * Felix Marti <felix@chelsio.com> *
31 * Scott Bardone <sbardone@chelsio.com> *
32 * Kurt Ottaway <kottaway@chelsio.com> *
33 * Frank DiMambro <frank@chelsio.com> *
34 * *
35 * History: *
36 * *
37 ****************************************************************************/
38
39#ifndef _CXGB_COMMON_H_
40#define _CXGB_COMMON_H_
41
42#include <linux/config.h>
43#include <linux/module.h>
44#include <linux/netdevice.h>
45#include <linux/types.h>
46#include <linux/delay.h>
47#include <linux/pci.h>
48#include <linux/ethtool.h>
49#include <linux/mii.h>
50#include <linux/crc32.h>
51#include <linux/init.h>
52#include <asm/io.h>
53#include <linux/pci_ids.h>
54
55#define DRV_DESCRIPTION "Chelsio 10Gb Ethernet Driver"
56#define DRV_NAME "cxgb"
57#define DRV_VERSION "2.1.1"
58#define PFX DRV_NAME ": "
59
60#define CH_ERR(fmt, ...) printk(KERN_ERR PFX fmt, ## __VA_ARGS__)
61#define CH_WARN(fmt, ...) printk(KERN_WARNING PFX fmt, ## __VA_ARGS__)
62#define CH_ALERT(fmt, ...) printk(KERN_ALERT PFX fmt, ## __VA_ARGS__)
63
64#define CH_DEVICE(devid, ssid, idx) \
65 { PCI_VENDOR_ID_CHELSIO, devid, PCI_ANY_ID, ssid, 0, 0, idx }
66
67#define SUPPORTED_PAUSE (1 << 13)
68#define SUPPORTED_LOOPBACK (1 << 15)
69
70#define ADVERTISED_PAUSE (1 << 13)
71#define ADVERTISED_ASYM_PAUSE (1 << 14)
72
73typedef struct adapter adapter_t;
74
75void t1_elmer0_ext_intr(adapter_t *adapter);
76void t1_link_changed(adapter_t *adapter, int port_id, int link_status,
77 int speed, int duplex, int fc);
78
79struct t1_rx_mode {
80 struct net_device *dev;
81 u32 idx;
82 struct dev_mc_list *list;
83};
84
85#define t1_rx_mode_promisc(rm) (rm->dev->flags & IFF_PROMISC)
86#define t1_rx_mode_allmulti(rm) (rm->dev->flags & IFF_ALLMULTI)
87#define t1_rx_mode_mc_cnt(rm) (rm->dev->mc_count)
88
89static inline u8 *t1_get_next_mcaddr(struct t1_rx_mode *rm)
90{
91 u8 *addr = 0;
92
93 if (rm->idx++ < rm->dev->mc_count) {
94 addr = rm->list->dmi_addr;
95 rm->list = rm->list->next;
96 }
97 return addr;
98}
99
100#define MAX_NPORTS 4
101
102#define SPEED_INVALID 0xffff
103#define DUPLEX_INVALID 0xff
104
105enum {
106 CHBT_BOARD_N110,
107 CHBT_BOARD_N210
108};
109
110enum {
111 CHBT_TERM_T1,
112 CHBT_TERM_T2
113};
114
115enum {
116 CHBT_MAC_PM3393,
117};
118
119enum {
120 CHBT_PHY_88X2010,
121};
122
123enum {
124 PAUSE_RX = 1 << 0,
125 PAUSE_TX = 1 << 1,
126 PAUSE_AUTONEG = 1 << 2
127};
128
129/* Revisions of T1 chip */
130enum {
131 TERM_T1A = 0,
132 TERM_T1B = 1,
133 TERM_T2 = 3
134};
135
136struct sge_params {
137 unsigned int cmdQ_size[2];
138 unsigned int freelQ_size[2];
139 unsigned int large_buf_capacity;
140 unsigned int rx_coalesce_usecs;
141 unsigned int last_rx_coalesce_raw;
142 unsigned int default_rx_coalesce_usecs;
143 unsigned int sample_interval_usecs;
144 unsigned int coalesce_enable;
145 unsigned int polling;
146};
147
148struct chelsio_pci_params {
149 unsigned short speed;
150 unsigned char width;
151 unsigned char is_pcix;
152};
153
154struct adapter_params {
155 struct sge_params sge;
156 struct chelsio_pci_params pci;
157
158 const struct board_info *brd_info;
159
160 unsigned int nports; /* # of ethernet ports */
161 unsigned int stats_update_period;
162 unsigned short chip_revision;
163 unsigned char chip_version;
164};
165
166struct link_config {
167 unsigned int supported; /* link capabilities */
168 unsigned int advertising; /* advertised capabilities */
169 unsigned short requested_speed; /* speed user has requested */
170 unsigned short speed; /* actual link speed */
171 unsigned char requested_duplex; /* duplex user has requested */
172 unsigned char duplex; /* actual link duplex */
173 unsigned char requested_fc; /* flow control user has requested */
174 unsigned char fc; /* actual link flow control */
175 unsigned char autoneg; /* autonegotiating? */
176};
177
178struct cmac;
179struct cphy;
180
181struct port_info {
182 struct net_device *dev;
183 struct cmac *mac;
184 struct cphy *phy;
185 struct link_config link_config;
186 struct net_device_stats netstats;
187};
188
189struct sge;
190struct peespi;
191
192struct adapter {
193 u8 *regs;
194 struct pci_dev *pdev;
195 unsigned long registered_device_map;
196 unsigned long open_device_map;
197 unsigned long flags;
198
199 const char *name;
200 int msg_enable;
201 u32 mmio_len;
202
203 struct work_struct ext_intr_handler_task;
204 struct adapter_params params;
205
206 struct vlan_group *vlan_grp;
207
208 /* Terminator modules. */
209 struct sge *sge;
210 struct peespi *espi;
211
212 struct port_info port[MAX_NPORTS];
213 struct work_struct stats_update_task;
214 struct timer_list stats_update_timer;
215
216 struct semaphore mib_mutex;
217 spinlock_t tpi_lock;
218 spinlock_t work_lock;
219 /* guards async operations */
220 spinlock_t async_lock ____cacheline_aligned;
221 u32 slow_intr_mask;
222};
223
224enum { /* adapter flags */
225 FULL_INIT_DONE = 1 << 0,
226 TSO_CAPABLE = 1 << 2,
227 TCP_CSUM_CAPABLE = 1 << 3,
228 UDP_CSUM_CAPABLE = 1 << 4,
229 VLAN_ACCEL_CAPABLE = 1 << 5,
230 RX_CSUM_ENABLED = 1 << 6,
231};
232
233struct mdio_ops;
234struct gmac;
235struct gphy;
236
237struct board_info {
238 unsigned char board;
239 unsigned char port_number;
240 unsigned long caps;
241 unsigned char chip_term;
242 unsigned char chip_mac;
243 unsigned char chip_phy;
244 unsigned int clock_core;
245 unsigned int clock_mc3;
246 unsigned int clock_mc4;
247 unsigned int espi_nports;
248 unsigned int clock_cspi;
249 unsigned int clock_elmer0;
250 unsigned char mdio_mdien;
251 unsigned char mdio_mdiinv;
252 unsigned char mdio_mdc;
253 unsigned char mdio_phybaseaddr;
254 struct gmac *gmac;
255 struct gphy *gphy;
256 struct mdio_ops *mdio_ops;
257 const char *desc;
258};
259
260extern struct pci_device_id t1_pci_tbl[];
261
262static inline int adapter_matches_type(const adapter_t *adapter,
263 int version, int revision)
264{
265 return adapter->params.chip_version == version &&
266 adapter->params.chip_revision == revision;
267}
268
269#define t1_is_T1B(adap) adapter_matches_type(adap, CHBT_TERM_T1, TERM_T1B)
270#define is_T2(adap) adapter_matches_type(adap, CHBT_TERM_T2, TERM_T2)
271
272/* Returns true if an adapter supports VLAN acceleration and TSO */
273static inline int vlan_tso_capable(const adapter_t *adapter)
274{
275 return !t1_is_T1B(adapter);
276}
277
278#define for_each_port(adapter, iter) \
279 for (iter = 0; iter < (adapter)->params.nports; ++iter)
280
281#define board_info(adapter) ((adapter)->params.brd_info)
282#define is_10G(adapter) (board_info(adapter)->caps & SUPPORTED_10000baseT_Full)
283
284static inline unsigned int core_ticks_per_usec(const adapter_t *adap)
285{
286 return board_info(adap)->clock_core / 1000000;
287}
288
289extern int t1_tpi_write(adapter_t *adapter, u32 addr, u32 value);
290extern int t1_tpi_read(adapter_t *adapter, u32 addr, u32 *value);
291
292extern void t1_interrupts_enable(adapter_t *adapter);
293extern void t1_interrupts_disable(adapter_t *adapter);
294extern void t1_interrupts_clear(adapter_t *adapter);
295extern int elmer0_ext_intr_handler(adapter_t *adapter);
296extern int t1_slow_intr_handler(adapter_t *adapter);
297
298extern int t1_link_start(struct cphy *phy, struct cmac *mac, struct link_config *lc);
299extern const struct board_info *t1_get_board_info(unsigned int board_id);
300extern const struct board_info *t1_get_board_info_from_ids(unsigned int devid,
301 unsigned short ssid);
302extern int t1_seeprom_read(adapter_t *adapter, u32 addr, u32 *data);
303extern int t1_get_board_rev(adapter_t *adapter, const struct board_info *bi,
304 struct adapter_params *p);
305extern int t1_init_hw_modules(adapter_t *adapter);
306extern int t1_init_sw_modules(adapter_t *adapter, const struct board_info *bi);
307extern void t1_free_sw_modules(adapter_t *adapter);
308extern void t1_fatal_err(adapter_t *adapter);
309
310extern void t1_tp_set_udp_checksum_offload(adapter_t *adapter, int enable);
311extern void t1_tp_set_tcp_checksum_offload(adapter_t *adapter, int enable);
312extern void t1_tp_set_ip_checksum_offload(adapter_t *adapter, int enable);
313
314#endif /* _CXGB_COMMON_H_ */
diff --git a/drivers/net/chelsio/cphy.h b/drivers/net/chelsio/cphy.h
new file mode 100644
index 000000000000..3412342f7345
--- /dev/null
+++ b/drivers/net/chelsio/cphy.h
@@ -0,0 +1,148 @@
1/*****************************************************************************
2 * *
3 * File: cphy.h *
4 * $Revision: 1.7 $ *
5 * $Date: 2005/06/21 18:29:47 $ *
6 * Description: *
7 * part of the Chelsio 10Gb Ethernet Driver. *
8 * *
9 * This program is free software; you can redistribute it and/or modify *
10 * it under the terms of the GNU General Public License, version 2, as *
11 * published by the Free Software Foundation. *
12 * *
13 * You should have received a copy of the GNU General Public License along *
14 * with this program; if not, write to the Free Software Foundation, Inc., *
15 * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
16 * *
17 * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED *
18 * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF *
19 * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. *
20 * *
21 * http://www.chelsio.com *
22 * *
23 * Copyright (c) 2003 - 2005 Chelsio Communications, Inc. *
24 * All rights reserved. *
25 * *
26 * Maintainers: maintainers@chelsio.com *
27 * *
28 * Authors: Dimitrios Michailidis <dm@chelsio.com> *
29 * Tina Yang <tainay@chelsio.com> *
30 * Felix Marti <felix@chelsio.com> *
31 * Scott Bardone <sbardone@chelsio.com> *
32 * Kurt Ottaway <kottaway@chelsio.com> *
33 * Frank DiMambro <frank@chelsio.com> *
34 * *
35 * History: *
36 * *
37 ****************************************************************************/
38
39#ifndef _CXGB_CPHY_H_
40#define _CXGB_CPHY_H_
41
42#include "common.h"
43
44struct mdio_ops {
45 void (*init)(adapter_t *adapter, const struct board_info *bi);
46 int (*read)(adapter_t *adapter, int phy_addr, int mmd_addr,
47 int reg_addr, unsigned int *val);
48 int (*write)(adapter_t *adapter, int phy_addr, int mmd_addr,
49 int reg_addr, unsigned int val);
50};
51
52/* PHY interrupt types */
53enum {
54 cphy_cause_link_change = 0x1,
55 cphy_cause_error = 0x2
56};
57
58struct cphy;
59
60/* PHY operations */
61struct cphy_ops {
62 void (*destroy)(struct cphy *);
63 int (*reset)(struct cphy *, int wait);
64
65 int (*interrupt_enable)(struct cphy *);
66 int (*interrupt_disable)(struct cphy *);
67 int (*interrupt_clear)(struct cphy *);
68 int (*interrupt_handler)(struct cphy *);
69
70 int (*autoneg_enable)(struct cphy *);
71 int (*autoneg_disable)(struct cphy *);
72 int (*autoneg_restart)(struct cphy *);
73
74 int (*advertise)(struct cphy *phy, unsigned int advertise_map);
75 int (*set_loopback)(struct cphy *, int on);
76 int (*set_speed_duplex)(struct cphy *phy, int speed, int duplex);
77 int (*get_link_status)(struct cphy *phy, int *link_ok, int *speed,
78 int *duplex, int *fc);
79};
80
81/* A PHY instance */
82struct cphy {
83 int addr; /* PHY address */
84 adapter_t *adapter; /* associated adapter */
85 struct cphy_ops *ops; /* PHY operations */
86 int (*mdio_read)(adapter_t *adapter, int phy_addr, int mmd_addr,
87 int reg_addr, unsigned int *val);
88 int (*mdio_write)(adapter_t *adapter, int phy_addr, int mmd_addr,
89 int reg_addr, unsigned int val);
90 struct cphy_instance *instance;
91};
92
93/* Convenience MDIO read/write wrappers */
94static inline int mdio_read(struct cphy *cphy, int mmd, int reg,
95 unsigned int *valp)
96{
97 return cphy->mdio_read(cphy->adapter, cphy->addr, mmd, reg, valp);
98}
99
100static inline int mdio_write(struct cphy *cphy, int mmd, int reg,
101 unsigned int val)
102{
103 return cphy->mdio_write(cphy->adapter, cphy->addr, mmd, reg, val);
104}
105
106static inline int simple_mdio_read(struct cphy *cphy, int reg,
107 unsigned int *valp)
108{
109 return mdio_read(cphy, 0, reg, valp);
110}
111
112static inline int simple_mdio_write(struct cphy *cphy, int reg,
113 unsigned int val)
114{
115 return mdio_write(cphy, 0, reg, val);
116}
117
118/* Convenience initializer */
119static inline void cphy_init(struct cphy *phy, adapter_t *adapter,
120 int phy_addr, struct cphy_ops *phy_ops,
121 struct mdio_ops *mdio_ops)
122{
123 phy->adapter = adapter;
124 phy->addr = phy_addr;
125 phy->ops = phy_ops;
126 if (mdio_ops) {
127 phy->mdio_read = mdio_ops->read;
128 phy->mdio_write = mdio_ops->write;
129 }
130}
131
132/* Operations of the PHY-instance factory */
133struct gphy {
134 /* Construct a PHY instance with the given PHY address */
135 struct cphy *(*create)(adapter_t *adapter, int phy_addr,
136 struct mdio_ops *mdio_ops);
137
138 /*
139 * Reset the PHY chip. This resets the whole PHY chip, not individual
140 * ports.
141 */
142 int (*reset)(adapter_t *adapter);
143};
144
145extern struct gphy t1_mv88x201x_ops;
146extern struct gphy t1_dummy_phy_ops;
147
148#endif /* _CXGB_CPHY_H_ */
diff --git a/drivers/net/chelsio/cpl5_cmd.h b/drivers/net/chelsio/cpl5_cmd.h
new file mode 100644
index 000000000000..27925e487bcf
--- /dev/null
+++ b/drivers/net/chelsio/cpl5_cmd.h
@@ -0,0 +1,145 @@
1/*****************************************************************************
2 * *
3 * File: cpl5_cmd.h *
4 * $Revision: 1.6 $ *
5 * $Date: 2005/06/21 18:29:47 $ *
6 * Description: *
7 * part of the Chelsio 10Gb Ethernet Driver. *
8 * *
9 * This program is free software; you can redistribute it and/or modify *
10 * it under the terms of the GNU General Public License, version 2, as *
11 * published by the Free Software Foundation. *
12 * *
13 * You should have received a copy of the GNU General Public License along *
14 * with this program; if not, write to the Free Software Foundation, Inc., *
15 * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
16 * *
17 * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED *
18 * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF *
19 * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. *
20 * *
21 * http://www.chelsio.com *
22 * *
23 * Copyright (c) 2003 - 2005 Chelsio Communications, Inc. *
24 * All rights reserved. *
25 * *
26 * Maintainers: maintainers@chelsio.com *
27 * *
28 * Authors: Dimitrios Michailidis <dm@chelsio.com> *
29 * Tina Yang <tainay@chelsio.com> *
30 * Felix Marti <felix@chelsio.com> *
31 * Scott Bardone <sbardone@chelsio.com> *
32 * Kurt Ottaway <kottaway@chelsio.com> *
33 * Frank DiMambro <frank@chelsio.com> *
34 * *
35 * History: *
36 * *
37 ****************************************************************************/
38
39#ifndef _CXGB_CPL5_CMD_H_
40#define _CXGB_CPL5_CMD_H_
41
42#include <asm/byteorder.h>
43
44#if !defined(__LITTLE_ENDIAN_BITFIELD) && !defined(__BIG_ENDIAN_BITFIELD)
45#error "Adjust your <asm/byteorder.h> defines"
46#endif
47
48enum CPL_opcode {
49 CPL_RX_PKT = 0xAD,
50 CPL_TX_PKT = 0xB2,
51 CPL_TX_PKT_LSO = 0xB6,
52};
53
54enum { /* TX_PKT_LSO ethernet types */
55 CPL_ETH_II,
56 CPL_ETH_II_VLAN,
57 CPL_ETH_802_3,
58 CPL_ETH_802_3_VLAN
59};
60
61struct cpl_rx_data {
62 u32 rsvd0;
63 u32 len;
64 u32 seq;
65 u16 urg;
66 u8 rsvd1;
67 u8 status;
68};
69
70/*
71 * We want this header's alignment to be no more stringent than 2-byte aligned.
72 * All fields are u8 or u16 except for the length. However that field is not
73 * used so we break it into 2 16-bit parts to easily meet our alignment needs.
74 */
75struct cpl_tx_pkt {
76 u8 opcode;
77#if defined(__LITTLE_ENDIAN_BITFIELD)
78 u8 iff:4;
79 u8 ip_csum_dis:1;
80 u8 l4_csum_dis:1;
81 u8 vlan_valid:1;
82 u8 rsvd:1;
83#else
84 u8 rsvd:1;
85 u8 vlan_valid:1;
86 u8 l4_csum_dis:1;
87 u8 ip_csum_dis:1;
88 u8 iff:4;
89#endif
90 u16 vlan;
91 u16 len_hi;
92 u16 len_lo;
93};
94
95struct cpl_tx_pkt_lso {
96 u8 opcode;
97#if defined(__LITTLE_ENDIAN_BITFIELD)
98 u8 iff:4;
99 u8 ip_csum_dis:1;
100 u8 l4_csum_dis:1;
101 u8 vlan_valid:1;
102 u8 rsvd:1;
103#else
104 u8 rsvd:1;
105 u8 vlan_valid:1;
106 u8 l4_csum_dis:1;
107 u8 ip_csum_dis:1;
108 u8 iff:4;
109#endif
110 u16 vlan;
111 u32 len;
112
113 u32 rsvd2;
114 u8 rsvd3;
115#if defined(__LITTLE_ENDIAN_BITFIELD)
116 u8 tcp_hdr_words:4;
117 u8 ip_hdr_words:4;
118#else
119 u8 ip_hdr_words:4;
120 u8 tcp_hdr_words:4;
121#endif
122 u16 eth_type_mss;
123};
124
125struct cpl_rx_pkt {
126 u8 opcode;
127#if defined(__LITTLE_ENDIAN_BITFIELD)
128 u8 iff:4;
129 u8 csum_valid:1;
130 u8 bad_pkt:1;
131 u8 vlan_valid:1;
132 u8 rsvd:1;
133#else
134 u8 rsvd:1;
135 u8 vlan_valid:1;
136 u8 bad_pkt:1;
137 u8 csum_valid:1;
138 u8 iff:4;
139#endif
140 u16 csum;
141 u16 vlan;
142 u16 len;
143};
144
145#endif /* _CXGB_CPL5_CMD_H_ */
diff --git a/drivers/net/chelsio/cxgb2.c b/drivers/net/chelsio/cxgb2.c
new file mode 100644
index 000000000000..28ae478b386d
--- /dev/null
+++ b/drivers/net/chelsio/cxgb2.c
@@ -0,0 +1,1256 @@
1/*****************************************************************************
2 * *
3 * File: cxgb2.c *
4 * $Revision: 1.25 $ *
5 * $Date: 2005/06/22 00:43:25 $ *
6 * Description: *
7 * Chelsio 10Gb Ethernet Driver. *
8 * *
9 * This program is free software; you can redistribute it and/or modify *
10 * it under the terms of the GNU General Public License, version 2, as *
11 * published by the Free Software Foundation. *
12 * *
13 * You should have received a copy of the GNU General Public License along *
14 * with this program; if not, write to the Free Software Foundation, Inc., *
15 * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
16 * *
17 * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED *
18 * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF *
19 * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. *
20 * *
21 * http://www.chelsio.com *
22 * *
23 * Copyright (c) 2003 - 2005 Chelsio Communications, Inc. *
24 * All rights reserved. *
25 * *
26 * Maintainers: maintainers@chelsio.com *
27 * *
28 * Authors: Dimitrios Michailidis <dm@chelsio.com> *
29 * Tina Yang <tainay@chelsio.com> *
30 * Felix Marti <felix@chelsio.com> *
31 * Scott Bardone <sbardone@chelsio.com> *
32 * Kurt Ottaway <kottaway@chelsio.com> *
33 * Frank DiMambro <frank@chelsio.com> *
34 * *
35 * History: *
36 * *
37 ****************************************************************************/
38
39#include "common.h"
40#include <linux/config.h>
41#include <linux/module.h>
42#include <linux/init.h>
43#include <linux/pci.h>
44#include <linux/netdevice.h>
45#include <linux/etherdevice.h>
46#include <linux/if_vlan.h>
47#include <linux/mii.h>
48#include <linux/sockios.h>
49#include <linux/proc_fs.h>
50#include <linux/dma-mapping.h>
51#include <asm/uaccess.h>
52
53#include "cpl5_cmd.h"
54#include "regs.h"
55#include "gmac.h"
56#include "cphy.h"
57#include "sge.h"
58#include "espi.h"
59
60#ifdef work_struct
61#include <linux/tqueue.h>
62#define INIT_WORK INIT_TQUEUE
63#define schedule_work schedule_task
64#define flush_scheduled_work flush_scheduled_tasks
65
66static inline void schedule_mac_stats_update(struct adapter *ap, int secs)
67{
68 mod_timer(&ap->stats_update_timer, jiffies + secs * HZ);
69}
70
71static inline void cancel_mac_stats_update(struct adapter *ap)
72{
73 del_timer_sync(&ap->stats_update_timer);
74 flush_scheduled_tasks();
75}
76
77/*
78 * Stats update timer for 2.4. It schedules a task to do the actual update as
79 * we need to access MAC statistics in process context.
80 */
81static void mac_stats_timer(unsigned long data)
82{
83 struct adapter *ap = (struct adapter *)data;
84
85 schedule_task(&ap->stats_update_task);
86}
87#else
88#include <linux/workqueue.h>
89
90static inline void schedule_mac_stats_update(struct adapter *ap, int secs)
91{
92 schedule_delayed_work(&ap->stats_update_task, secs * HZ);
93}
94
95static inline void cancel_mac_stats_update(struct adapter *ap)
96{
97 cancel_delayed_work(&ap->stats_update_task);
98}
99#endif
100
101#define MAX_CMDQ_ENTRIES 16384
102#define MAX_CMDQ1_ENTRIES 1024
103#define MAX_RX_BUFFERS 16384
104#define MAX_RX_JUMBO_BUFFERS 16384
105#define MAX_TX_BUFFERS_HIGH 16384U
106#define MAX_TX_BUFFERS_LOW 1536U
107#define MIN_FL_ENTRIES 32
108
109#define PORT_MASK ((1 << MAX_NPORTS) - 1)
110
111#define DFLT_MSG_ENABLE (NETIF_MSG_DRV | NETIF_MSG_PROBE | NETIF_MSG_LINK | \
112 NETIF_MSG_TIMER | NETIF_MSG_IFDOWN | NETIF_MSG_IFUP |\
113 NETIF_MSG_RX_ERR | NETIF_MSG_TX_ERR)
114
115/*
116 * The EEPROM is actually bigger but only the first few bytes are used so we
117 * only report those.
118 */
119#define EEPROM_SIZE 32
120
121MODULE_DESCRIPTION(DRV_DESCRIPTION);
122MODULE_AUTHOR("Chelsio Communications");
123MODULE_LICENSE("GPL");
124
125static int dflt_msg_enable = DFLT_MSG_ENABLE;
126
127MODULE_PARM(dflt_msg_enable, "i");
128MODULE_PARM_DESC(dflt_msg_enable, "Chelsio T1 message enable bitmap");
129
130
131static const char pci_speed[][4] = {
132 "33", "66", "100", "133"
133};
134
135/*
136 * Setup MAC to receive the types of packets we want.
137 */
138static void t1_set_rxmode(struct net_device *dev)
139{
140 struct adapter *adapter = dev->priv;
141 struct cmac *mac = adapter->port[dev->if_port].mac;
142 struct t1_rx_mode rm;
143
144 rm.dev = dev;
145 rm.idx = 0;
146 rm.list = dev->mc_list;
147 mac->ops->set_rx_mode(mac, &rm);
148}
149
150static void link_report(struct port_info *p)
151{
152 if (!netif_carrier_ok(p->dev))
153 printk(KERN_INFO "%s: link down\n", p->dev->name);
154 else {
155 const char *s = "10Mbps";
156
157 switch (p->link_config.speed) {
158 case SPEED_10000: s = "10Gbps"; break;
159 case SPEED_1000: s = "1000Mbps"; break;
160 case SPEED_100: s = "100Mbps"; break;
161 }
162
163 printk(KERN_INFO "%s: link up, %s, %s-duplex\n",
164 p->dev->name, s,
165 p->link_config.duplex == DUPLEX_FULL ? "full" : "half");
166 }
167}
168
169void t1_link_changed(struct adapter *adapter, int port_id, int link_stat,
170 int speed, int duplex, int pause)
171{
172 struct port_info *p = &adapter->port[port_id];
173
174 if (link_stat != netif_carrier_ok(p->dev)) {
175 if (link_stat)
176 netif_carrier_on(p->dev);
177 else
178 netif_carrier_off(p->dev);
179 link_report(p);
180
181 }
182}
183
184static void link_start(struct port_info *p)
185{
186 struct cmac *mac = p->mac;
187
188 mac->ops->reset(mac);
189 if (mac->ops->macaddress_set)
190 mac->ops->macaddress_set(mac, p->dev->dev_addr);
191 t1_set_rxmode(p->dev);
192 t1_link_start(p->phy, mac, &p->link_config);
193 mac->ops->enable(mac, MAC_DIRECTION_RX | MAC_DIRECTION_TX);
194}
195
196static void enable_hw_csum(struct adapter *adapter)
197{
198 if (adapter->flags & TSO_CAPABLE)
199 t1_tp_set_ip_checksum_offload(adapter, 1); /* for TSO only */
200 t1_tp_set_tcp_checksum_offload(adapter, 1);
201}
202
203/*
204 * Things to do upon first use of a card.
205 * This must run with the rtnl lock held.
206 */
207static int cxgb_up(struct adapter *adapter)
208{
209 int err = 0;
210
211 if (!(adapter->flags & FULL_INIT_DONE)) {
212 err = t1_init_hw_modules(adapter);
213 if (err)
214 goto out_err;
215
216 enable_hw_csum(adapter);
217 adapter->flags |= FULL_INIT_DONE;
218 }
219
220 t1_interrupts_clear(adapter);
221 if ((err = request_irq(adapter->pdev->irq,
222 t1_select_intr_handler(adapter), SA_SHIRQ,
223 adapter->name, adapter))) {
224 goto out_err;
225 }
226 t1_sge_start(adapter->sge);
227 t1_interrupts_enable(adapter);
228 out_err:
229 return err;
230}
231
232/*
233 * Release resources when all the ports have been stopped.
234 */
235static void cxgb_down(struct adapter *adapter)
236{
237 t1_sge_stop(adapter->sge);
238 t1_interrupts_disable(adapter);
239 free_irq(adapter->pdev->irq, adapter);
240}
241
242static int cxgb_open(struct net_device *dev)
243{
244 int err;
245 struct adapter *adapter = dev->priv;
246 int other_ports = adapter->open_device_map & PORT_MASK;
247
248 if (!adapter->open_device_map && (err = cxgb_up(adapter)) < 0)
249 return err;
250
251 __set_bit(dev->if_port, &adapter->open_device_map);
252 link_start(&adapter->port[dev->if_port]);
253 netif_start_queue(dev);
254 if (!other_ports && adapter->params.stats_update_period)
255 schedule_mac_stats_update(adapter,
256 adapter->params.stats_update_period);
257 return 0;
258}
259
260static int cxgb_close(struct net_device *dev)
261{
262 struct adapter *adapter = dev->priv;
263 struct port_info *p = &adapter->port[dev->if_port];
264 struct cmac *mac = p->mac;
265
266 netif_stop_queue(dev);
267 mac->ops->disable(mac, MAC_DIRECTION_TX | MAC_DIRECTION_RX);
268 netif_carrier_off(dev);
269
270 clear_bit(dev->if_port, &adapter->open_device_map);
271 if (adapter->params.stats_update_period &&
272 !(adapter->open_device_map & PORT_MASK)) {
273 /* Stop statistics accumulation. */
274 smp_mb__after_clear_bit();
275 spin_lock(&adapter->work_lock); /* sync with update task */
276 spin_unlock(&adapter->work_lock);
277 cancel_mac_stats_update(adapter);
278 }
279
280 if (!adapter->open_device_map)
281 cxgb_down(adapter);
282 return 0;
283}
284
285static struct net_device_stats *t1_get_stats(struct net_device *dev)
286{
287 struct adapter *adapter = dev->priv;
288 struct port_info *p = &adapter->port[dev->if_port];
289 struct net_device_stats *ns = &p->netstats;
290 const struct cmac_statistics *pstats;
291
292 /* Do a full update of the MAC stats */
293 pstats = p->mac->ops->statistics_update(p->mac,
294 MAC_STATS_UPDATE_FULL);
295
296 ns->tx_packets = pstats->TxUnicastFramesOK +
297 pstats->TxMulticastFramesOK + pstats->TxBroadcastFramesOK;
298
299 ns->rx_packets = pstats->RxUnicastFramesOK +
300 pstats->RxMulticastFramesOK + pstats->RxBroadcastFramesOK;
301
302 ns->tx_bytes = pstats->TxOctetsOK;
303 ns->rx_bytes = pstats->RxOctetsOK;
304
305 ns->tx_errors = pstats->TxLateCollisions + pstats->TxLengthErrors +
306 pstats->TxUnderrun + pstats->TxFramesAbortedDueToXSCollisions;
307 ns->rx_errors = pstats->RxDataErrors + pstats->RxJabberErrors +
308 pstats->RxFCSErrors + pstats->RxAlignErrors +
309 pstats->RxSequenceErrors + pstats->RxFrameTooLongErrors +
310 pstats->RxSymbolErrors + pstats->RxRuntErrors;
311
312 ns->multicast = pstats->RxMulticastFramesOK;
313 ns->collisions = pstats->TxTotalCollisions;
314
315 /* detailed rx_errors */
316 ns->rx_length_errors = pstats->RxFrameTooLongErrors +
317 pstats->RxJabberErrors;
318 ns->rx_over_errors = 0;
319 ns->rx_crc_errors = pstats->RxFCSErrors;
320 ns->rx_frame_errors = pstats->RxAlignErrors;
321 ns->rx_fifo_errors = 0;
322 ns->rx_missed_errors = 0;
323
324 /* detailed tx_errors */
325 ns->tx_aborted_errors = pstats->TxFramesAbortedDueToXSCollisions;
326 ns->tx_carrier_errors = 0;
327 ns->tx_fifo_errors = pstats->TxUnderrun;
328 ns->tx_heartbeat_errors = 0;
329 ns->tx_window_errors = pstats->TxLateCollisions;
330 return ns;
331}
332
333static u32 get_msglevel(struct net_device *dev)
334{
335 struct adapter *adapter = dev->priv;
336
337 return adapter->msg_enable;
338}
339
340static void set_msglevel(struct net_device *dev, u32 val)
341{
342 struct adapter *adapter = dev->priv;
343
344 adapter->msg_enable = val;
345}
346
347static char stats_strings[][ETH_GSTRING_LEN] = {
348 "TxOctetsOK",
349 "TxOctetsBad",
350 "TxUnicastFramesOK",
351 "TxMulticastFramesOK",
352 "TxBroadcastFramesOK",
353 "TxPauseFrames",
354 "TxFramesWithDeferredXmissions",
355 "TxLateCollisions",
356 "TxTotalCollisions",
357 "TxFramesAbortedDueToXSCollisions",
358 "TxUnderrun",
359 "TxLengthErrors",
360 "TxInternalMACXmitError",
361 "TxFramesWithExcessiveDeferral",
362 "TxFCSErrors",
363
364 "RxOctetsOK",
365 "RxOctetsBad",
366 "RxUnicastFramesOK",
367 "RxMulticastFramesOK",
368 "RxBroadcastFramesOK",
369 "RxPauseFrames",
370 "RxFCSErrors",
371 "RxAlignErrors",
372 "RxSymbolErrors",
373 "RxDataErrors",
374 "RxSequenceErrors",
375 "RxRuntErrors",
376 "RxJabberErrors",
377 "RxInternalMACRcvError",
378 "RxInRangeLengthErrors",
379 "RxOutOfRangeLengthField",
380 "RxFrameTooLongErrors",
381
382 "TSO",
383 "VLANextractions",
384 "VLANinsertions",
385 "RxCsumGood",
386 "TxCsumOffload",
387 "RxDrops"
388
389 "respQ_empty",
390 "respQ_overflow",
391 "freelistQ_empty",
392 "pkt_too_big",
393 "pkt_mismatch",
394 "cmdQ_full0",
395 "cmdQ_full1",
396 "tx_ipfrags",
397 "tx_reg_pkts",
398 "tx_lso_pkts",
399 "tx_do_cksum",
400
401 "espi_DIP2ParityErr",
402 "espi_DIP4Err",
403 "espi_RxDrops",
404 "espi_TxDrops",
405 "espi_RxOvfl",
406 "espi_ParityErr"
407};
408
409#define T2_REGMAP_SIZE (3 * 1024)
410
411static int get_regs_len(struct net_device *dev)
412{
413 return T2_REGMAP_SIZE;
414}
415
416static void get_drvinfo(struct net_device *dev, struct ethtool_drvinfo *info)
417{
418 struct adapter *adapter = dev->priv;
419
420 strcpy(info->driver, DRV_NAME);
421 strcpy(info->version, DRV_VERSION);
422 strcpy(info->fw_version, "N/A");
423 strcpy(info->bus_info, pci_name(adapter->pdev));
424}
425
426static int get_stats_count(struct net_device *dev)
427{
428 return ARRAY_SIZE(stats_strings);
429}
430
431static void get_strings(struct net_device *dev, u32 stringset, u8 *data)
432{
433 if (stringset == ETH_SS_STATS)
434 memcpy(data, stats_strings, sizeof(stats_strings));
435}
436
437static void get_stats(struct net_device *dev, struct ethtool_stats *stats,
438 u64 *data)
439{
440 struct adapter *adapter = dev->priv;
441 struct cmac *mac = adapter->port[dev->if_port].mac;
442 const struct cmac_statistics *s;
443 const struct sge_port_stats *ss;
444 const struct sge_intr_counts *t;
445
446 s = mac->ops->statistics_update(mac, MAC_STATS_UPDATE_FULL);
447 ss = t1_sge_get_port_stats(adapter->sge, dev->if_port);
448 t = t1_sge_get_intr_counts(adapter->sge);
449
450 *data++ = s->TxOctetsOK;
451 *data++ = s->TxOctetsBad;
452 *data++ = s->TxUnicastFramesOK;
453 *data++ = s->TxMulticastFramesOK;
454 *data++ = s->TxBroadcastFramesOK;
455 *data++ = s->TxPauseFrames;
456 *data++ = s->TxFramesWithDeferredXmissions;
457 *data++ = s->TxLateCollisions;
458 *data++ = s->TxTotalCollisions;
459 *data++ = s->TxFramesAbortedDueToXSCollisions;
460 *data++ = s->TxUnderrun;
461 *data++ = s->TxLengthErrors;
462 *data++ = s->TxInternalMACXmitError;
463 *data++ = s->TxFramesWithExcessiveDeferral;
464 *data++ = s->TxFCSErrors;
465
466 *data++ = s->RxOctetsOK;
467 *data++ = s->RxOctetsBad;
468 *data++ = s->RxUnicastFramesOK;
469 *data++ = s->RxMulticastFramesOK;
470 *data++ = s->RxBroadcastFramesOK;
471 *data++ = s->RxPauseFrames;
472 *data++ = s->RxFCSErrors;
473 *data++ = s->RxAlignErrors;
474 *data++ = s->RxSymbolErrors;
475 *data++ = s->RxDataErrors;
476 *data++ = s->RxSequenceErrors;
477 *data++ = s->RxRuntErrors;
478 *data++ = s->RxJabberErrors;
479 *data++ = s->RxInternalMACRcvError;
480 *data++ = s->RxInRangeLengthErrors;
481 *data++ = s->RxOutOfRangeLengthField;
482 *data++ = s->RxFrameTooLongErrors;
483
484 *data++ = ss->tso;
485 *data++ = ss->vlan_xtract;
486 *data++ = ss->vlan_insert;
487 *data++ = ss->rx_cso_good;
488 *data++ = ss->tx_cso;
489 *data++ = ss->rx_drops;
490
491 *data++ = (u64)t->respQ_empty;
492 *data++ = (u64)t->respQ_overflow;
493 *data++ = (u64)t->freelistQ_empty;
494 *data++ = (u64)t->pkt_too_big;
495 *data++ = (u64)t->pkt_mismatch;
496 *data++ = (u64)t->cmdQ_full[0];
497 *data++ = (u64)t->cmdQ_full[1];
498 *data++ = (u64)t->tx_ipfrags;
499 *data++ = (u64)t->tx_reg_pkts;
500 *data++ = (u64)t->tx_lso_pkts;
501 *data++ = (u64)t->tx_do_cksum;
502}
503
504static inline void reg_block_dump(struct adapter *ap, void *buf,
505 unsigned int start, unsigned int end)
506{
507 u32 *p = buf + start;
508
509 for ( ; start <= end; start += sizeof(u32))
510 *p++ = readl(ap->regs + start);
511}
512
513static void get_regs(struct net_device *dev, struct ethtool_regs *regs,
514 void *buf)
515{
516 struct adapter *ap = dev->priv;
517
518 /*
519 * Version scheme: bits 0..9: chip version, bits 10..15: chip revision
520 */
521 regs->version = 2;
522
523 memset(buf, 0, T2_REGMAP_SIZE);
524 reg_block_dump(ap, buf, 0, A_SG_RESPACCUTIMER);
525}
526
527static int get_settings(struct net_device *dev, struct ethtool_cmd *cmd)
528{
529 struct adapter *adapter = dev->priv;
530 struct port_info *p = &adapter->port[dev->if_port];
531
532 cmd->supported = p->link_config.supported;
533 cmd->advertising = p->link_config.advertising;
534
535 if (netif_carrier_ok(dev)) {
536 cmd->speed = p->link_config.speed;
537 cmd->duplex = p->link_config.duplex;
538 } else {
539 cmd->speed = -1;
540 cmd->duplex = -1;
541 }
542
543 cmd->port = (cmd->supported & SUPPORTED_TP) ? PORT_TP : PORT_FIBRE;
544 cmd->phy_address = p->phy->addr;
545 cmd->transceiver = XCVR_EXTERNAL;
546 cmd->autoneg = p->link_config.autoneg;
547 cmd->maxtxpkt = 0;
548 cmd->maxrxpkt = 0;
549 return 0;
550}
551
552static int speed_duplex_to_caps(int speed, int duplex)
553{
554 int cap = 0;
555
556 switch (speed) {
557 case SPEED_10:
558 if (duplex == DUPLEX_FULL)
559 cap = SUPPORTED_10baseT_Full;
560 else
561 cap = SUPPORTED_10baseT_Half;
562 break;
563 case SPEED_100:
564 if (duplex == DUPLEX_FULL)
565 cap = SUPPORTED_100baseT_Full;
566 else
567 cap = SUPPORTED_100baseT_Half;
568 break;
569 case SPEED_1000:
570 if (duplex == DUPLEX_FULL)
571 cap = SUPPORTED_1000baseT_Full;
572 else
573 cap = SUPPORTED_1000baseT_Half;
574 break;
575 case SPEED_10000:
576 if (duplex == DUPLEX_FULL)
577 cap = SUPPORTED_10000baseT_Full;
578 }
579 return cap;
580}
581
582#define ADVERTISED_MASK (ADVERTISED_10baseT_Half | ADVERTISED_10baseT_Full | \
583 ADVERTISED_100baseT_Half | ADVERTISED_100baseT_Full | \
584 ADVERTISED_1000baseT_Half | ADVERTISED_1000baseT_Full | \
585 ADVERTISED_10000baseT_Full)
586
587static int set_settings(struct net_device *dev, struct ethtool_cmd *cmd)
588{
589 struct adapter *adapter = dev->priv;
590 struct port_info *p = &adapter->port[dev->if_port];
591 struct link_config *lc = &p->link_config;
592
593 if (!(lc->supported & SUPPORTED_Autoneg))
594 return -EOPNOTSUPP; /* can't change speed/duplex */
595
596 if (cmd->autoneg == AUTONEG_DISABLE) {
597 int cap = speed_duplex_to_caps(cmd->speed, cmd->duplex);
598
599 if (!(lc->supported & cap) || cmd->speed == SPEED_1000)
600 return -EINVAL;
601 lc->requested_speed = cmd->speed;
602 lc->requested_duplex = cmd->duplex;
603 lc->advertising = 0;
604 } else {
605 cmd->advertising &= ADVERTISED_MASK;
606 if (cmd->advertising & (cmd->advertising - 1))
607 cmd->advertising = lc->supported;
608 cmd->advertising &= lc->supported;
609 if (!cmd->advertising)
610 return -EINVAL;
611 lc->requested_speed = SPEED_INVALID;
612 lc->requested_duplex = DUPLEX_INVALID;
613 lc->advertising = cmd->advertising | ADVERTISED_Autoneg;
614 }
615 lc->autoneg = cmd->autoneg;
616 if (netif_running(dev))
617 t1_link_start(p->phy, p->mac, lc);
618 return 0;
619}
620
621static void get_pauseparam(struct net_device *dev,
622 struct ethtool_pauseparam *epause)
623{
624 struct adapter *adapter = dev->priv;
625 struct port_info *p = &adapter->port[dev->if_port];
626
627 epause->autoneg = (p->link_config.requested_fc & PAUSE_AUTONEG) != 0;
628 epause->rx_pause = (p->link_config.fc & PAUSE_RX) != 0;
629 epause->tx_pause = (p->link_config.fc & PAUSE_TX) != 0;
630}
631
632static int set_pauseparam(struct net_device *dev,
633 struct ethtool_pauseparam *epause)
634{
635 struct adapter *adapter = dev->priv;
636 struct port_info *p = &adapter->port[dev->if_port];
637 struct link_config *lc = &p->link_config;
638
639 if (epause->autoneg == AUTONEG_DISABLE)
640 lc->requested_fc = 0;
641 else if (lc->supported & SUPPORTED_Autoneg)
642 lc->requested_fc = PAUSE_AUTONEG;
643 else
644 return -EINVAL;
645
646 if (epause->rx_pause)
647 lc->requested_fc |= PAUSE_RX;
648 if (epause->tx_pause)
649 lc->requested_fc |= PAUSE_TX;
650 if (lc->autoneg == AUTONEG_ENABLE) {
651 if (netif_running(dev))
652 t1_link_start(p->phy, p->mac, lc);
653 } else {
654 lc->fc = lc->requested_fc & (PAUSE_RX | PAUSE_TX);
655 if (netif_running(dev))
656 p->mac->ops->set_speed_duplex_fc(p->mac, -1, -1,
657 lc->fc);
658 }
659 return 0;
660}
661
662static u32 get_rx_csum(struct net_device *dev)
663{
664 struct adapter *adapter = dev->priv;
665
666 return (adapter->flags & RX_CSUM_ENABLED) != 0;
667}
668
669static int set_rx_csum(struct net_device *dev, u32 data)
670{
671 struct adapter *adapter = dev->priv;
672
673 if (data)
674 adapter->flags |= RX_CSUM_ENABLED;
675 else
676 adapter->flags &= ~RX_CSUM_ENABLED;
677 return 0;
678}
679
680static int set_tso(struct net_device *dev, u32 value)
681{
682 struct adapter *adapter = dev->priv;
683
684 if (!(adapter->flags & TSO_CAPABLE))
685 return value ? -EOPNOTSUPP : 0;
686 return ethtool_op_set_tso(dev, value);
687}
688
689static void get_sge_param(struct net_device *dev, struct ethtool_ringparam *e)
690{
691 struct adapter *adapter = dev->priv;
692 int jumbo_fl = t1_is_T1B(adapter) ? 1 : 0;
693
694 e->rx_max_pending = MAX_RX_BUFFERS;
695 e->rx_mini_max_pending = 0;
696 e->rx_jumbo_max_pending = MAX_RX_JUMBO_BUFFERS;
697 e->tx_max_pending = MAX_CMDQ_ENTRIES;
698
699 e->rx_pending = adapter->params.sge.freelQ_size[!jumbo_fl];
700 e->rx_mini_pending = 0;
701 e->rx_jumbo_pending = adapter->params.sge.freelQ_size[jumbo_fl];
702 e->tx_pending = adapter->params.sge.cmdQ_size[0];
703}
704
705static int set_sge_param(struct net_device *dev, struct ethtool_ringparam *e)
706{
707 struct adapter *adapter = dev->priv;
708 int jumbo_fl = t1_is_T1B(adapter) ? 1 : 0;
709
710 if (e->rx_pending > MAX_RX_BUFFERS || e->rx_mini_pending ||
711 e->rx_jumbo_pending > MAX_RX_JUMBO_BUFFERS ||
712 e->tx_pending > MAX_CMDQ_ENTRIES ||
713 e->rx_pending < MIN_FL_ENTRIES ||
714 e->rx_jumbo_pending < MIN_FL_ENTRIES ||
715 e->tx_pending < (adapter->params.nports + 1) * (MAX_SKB_FRAGS + 1))
716 return -EINVAL;
717
718 if (adapter->flags & FULL_INIT_DONE)
719 return -EBUSY;
720
721 adapter->params.sge.freelQ_size[!jumbo_fl] = e->rx_pending;
722 adapter->params.sge.freelQ_size[jumbo_fl] = e->rx_jumbo_pending;
723 adapter->params.sge.cmdQ_size[0] = e->tx_pending;
724 adapter->params.sge.cmdQ_size[1] = e->tx_pending > MAX_CMDQ1_ENTRIES ?
725 MAX_CMDQ1_ENTRIES : e->tx_pending;
726 return 0;
727}
728
729static int set_coalesce(struct net_device *dev, struct ethtool_coalesce *c)
730{
731 struct adapter *adapter = dev->priv;
732
733 /*
734 * If RX coalescing is requested we use NAPI, otherwise interrupts.
735 * This choice can be made only when all ports and the TOE are off.
736 */
737 if (adapter->open_device_map == 0)
738 adapter->params.sge.polling = c->use_adaptive_rx_coalesce;
739
740 if (adapter->params.sge.polling) {
741 adapter->params.sge.rx_coalesce_usecs = 0;
742 } else {
743 adapter->params.sge.rx_coalesce_usecs = c->rx_coalesce_usecs;
744 }
745 adapter->params.sge.coalesce_enable = c->use_adaptive_rx_coalesce;
746 adapter->params.sge.sample_interval_usecs = c->rate_sample_interval;
747 t1_sge_set_coalesce_params(adapter->sge, &adapter->params.sge);
748 return 0;
749}
750
751static int get_coalesce(struct net_device *dev, struct ethtool_coalesce *c)
752{
753 struct adapter *adapter = dev->priv;
754
755 c->rx_coalesce_usecs = adapter->params.sge.rx_coalesce_usecs;
756 c->rate_sample_interval = adapter->params.sge.sample_interval_usecs;
757 c->use_adaptive_rx_coalesce = adapter->params.sge.coalesce_enable;
758 return 0;
759}
760
761static int get_eeprom_len(struct net_device *dev)
762{
763 return EEPROM_SIZE;
764}
765
766#define EEPROM_MAGIC(ap) \
767 (PCI_VENDOR_ID_CHELSIO | ((ap)->params.chip_version << 16))
768
769static int get_eeprom(struct net_device *dev, struct ethtool_eeprom *e,
770 u8 *data)
771{
772 int i;
773 u8 buf[EEPROM_SIZE] __attribute__((aligned(4)));
774 struct adapter *adapter = dev->priv;
775
776 e->magic = EEPROM_MAGIC(adapter);
777 for (i = e->offset & ~3; i < e->offset + e->len; i += sizeof(u32))
778 t1_seeprom_read(adapter, i, (u32 *)&buf[i]);
779 memcpy(data, buf + e->offset, e->len);
780 return 0;
781}
782
783static struct ethtool_ops t1_ethtool_ops = {
784 .get_settings = get_settings,
785 .set_settings = set_settings,
786 .get_drvinfo = get_drvinfo,
787 .get_msglevel = get_msglevel,
788 .set_msglevel = set_msglevel,
789 .get_ringparam = get_sge_param,
790 .set_ringparam = set_sge_param,
791 .get_coalesce = get_coalesce,
792 .set_coalesce = set_coalesce,
793 .get_eeprom_len = get_eeprom_len,
794 .get_eeprom = get_eeprom,
795 .get_pauseparam = get_pauseparam,
796 .set_pauseparam = set_pauseparam,
797 .get_rx_csum = get_rx_csum,
798 .set_rx_csum = set_rx_csum,
799 .get_tx_csum = ethtool_op_get_tx_csum,
800 .set_tx_csum = ethtool_op_set_tx_csum,
801 .get_sg = ethtool_op_get_sg,
802 .set_sg = ethtool_op_set_sg,
803 .get_link = ethtool_op_get_link,
804 .get_strings = get_strings,
805 .get_stats_count = get_stats_count,
806 .get_ethtool_stats = get_stats,
807 .get_regs_len = get_regs_len,
808 .get_regs = get_regs,
809 .get_tso = ethtool_op_get_tso,
810 .set_tso = set_tso,
811};
812
813static void cxgb_proc_cleanup(struct adapter *adapter,
814 struct proc_dir_entry *dir)
815{
816 const char *name;
817 name = adapter->name;
818 remove_proc_entry(name, dir);
819}
820//#define chtoe_setup_toedev(adapter) NULL
821#define update_mtu_tab(adapter)
822#define write_smt_entry(adapter, idx)
823
824static int t1_ioctl(struct net_device *dev, struct ifreq *req, int cmd)
825{
826 struct adapter *adapter = dev->priv;
827 struct mii_ioctl_data *data = (struct mii_ioctl_data *)&req->ifr_data;
828
829 switch (cmd) {
830 case SIOCGMIIPHY:
831 data->phy_id = adapter->port[dev->if_port].phy->addr;
832 /* FALLTHRU */
833 case SIOCGMIIREG: {
834 struct cphy *phy = adapter->port[dev->if_port].phy;
835 u32 val;
836
837 if (!phy->mdio_read)
838 return -EOPNOTSUPP;
839 phy->mdio_read(adapter, data->phy_id, 0, data->reg_num & 0x1f,
840 &val);
841 data->val_out = val;
842 break;
843 }
844 case SIOCSMIIREG: {
845 struct cphy *phy = adapter->port[dev->if_port].phy;
846
847 if (!capable(CAP_NET_ADMIN))
848 return -EPERM;
849 if (!phy->mdio_write)
850 return -EOPNOTSUPP;
851 phy->mdio_write(adapter, data->phy_id, 0, data->reg_num & 0x1f,
852 data->val_in);
853 break;
854 }
855
856 default:
857 return -EOPNOTSUPP;
858 }
859 return 0;
860}
861
862static int t1_change_mtu(struct net_device *dev, int new_mtu)
863{
864 int ret;
865 struct adapter *adapter = dev->priv;
866 struct cmac *mac = adapter->port[dev->if_port].mac;
867
868 if (!mac->ops->set_mtu)
869 return -EOPNOTSUPP;
870 if (new_mtu < 68)
871 return -EINVAL;
872 if ((ret = mac->ops->set_mtu(mac, new_mtu)))
873 return ret;
874 dev->mtu = new_mtu;
875 return 0;
876}
877
878static int t1_set_mac_addr(struct net_device *dev, void *p)
879{
880 struct adapter *adapter = dev->priv;
881 struct cmac *mac = adapter->port[dev->if_port].mac;
882 struct sockaddr *addr = p;
883
884 if (!mac->ops->macaddress_set)
885 return -EOPNOTSUPP;
886
887 memcpy(dev->dev_addr, addr->sa_data, dev->addr_len);
888 mac->ops->macaddress_set(mac, dev->dev_addr);
889 return 0;
890}
891
892#if defined(CONFIG_VLAN_8021Q) || defined(CONFIG_VLAN_8021Q_MODULE)
893static void vlan_rx_register(struct net_device *dev,
894 struct vlan_group *grp)
895{
896 struct adapter *adapter = dev->priv;
897
898 spin_lock_irq(&adapter->async_lock);
899 adapter->vlan_grp = grp;
900 t1_set_vlan_accel(adapter, grp != NULL);
901 spin_unlock_irq(&adapter->async_lock);
902}
903
904static void vlan_rx_kill_vid(struct net_device *dev, unsigned short vid)
905{
906 struct adapter *adapter = dev->priv;
907
908 spin_lock_irq(&adapter->async_lock);
909 if (adapter->vlan_grp)
910 adapter->vlan_grp->vlan_devices[vid] = NULL;
911 spin_unlock_irq(&adapter->async_lock);
912}
913#endif
914
915#ifdef CONFIG_NET_POLL_CONTROLLER
916static void t1_netpoll(struct net_device *dev)
917{
918 unsigned long flags;
919 struct adapter *adapter = dev->priv;
920
921 local_irq_save(flags);
922 t1_select_intr_handler(adapter)(adapter->pdev->irq, adapter, NULL);
923 local_irq_restore(flags);
924}
925#endif
926
927/*
928 * Periodic accumulation of MAC statistics. This is used only if the MAC
929 * does not have any other way to prevent stats counter overflow.
930 */
931static void mac_stats_task(void *data)
932{
933 int i;
934 struct adapter *adapter = data;
935
936 for_each_port(adapter, i) {
937 struct port_info *p = &adapter->port[i];
938
939 if (netif_running(p->dev))
940 p->mac->ops->statistics_update(p->mac,
941 MAC_STATS_UPDATE_FAST);
942 }
943
944 /* Schedule the next statistics update if any port is active. */
945 spin_lock(&adapter->work_lock);
946 if (adapter->open_device_map & PORT_MASK)
947 schedule_mac_stats_update(adapter,
948 adapter->params.stats_update_period);
949 spin_unlock(&adapter->work_lock);
950}
951
952/*
953 * Processes elmer0 external interrupts in process context.
954 */
955static void ext_intr_task(void *data)
956{
957 struct adapter *adapter = data;
958
959 elmer0_ext_intr_handler(adapter);
960
961 /* Now reenable external interrupts */
962 spin_lock_irq(&adapter->async_lock);
963 adapter->slow_intr_mask |= F_PL_INTR_EXT;
964 writel(F_PL_INTR_EXT, adapter->regs + A_PL_CAUSE);
965 writel(adapter->slow_intr_mask | F_PL_INTR_SGE_DATA,
966 adapter->regs + A_PL_ENABLE);
967 spin_unlock_irq(&adapter->async_lock);
968}
969
970/*
971 * Interrupt-context handler for elmer0 external interrupts.
972 */
973void t1_elmer0_ext_intr(struct adapter *adapter)
974{
975 /*
976 * Schedule a task to handle external interrupts as we require
977 * a process context. We disable EXT interrupts in the interim
978 * and let the task reenable them when it's done.
979 */
980 adapter->slow_intr_mask &= ~F_PL_INTR_EXT;
981 writel(adapter->slow_intr_mask | F_PL_INTR_SGE_DATA,
982 adapter->regs + A_PL_ENABLE);
983 schedule_work(&adapter->ext_intr_handler_task);
984}
985
986void t1_fatal_err(struct adapter *adapter)
987{
988 if (adapter->flags & FULL_INIT_DONE) {
989 t1_sge_stop(adapter->sge);
990 t1_interrupts_disable(adapter);
991 }
992 CH_ALERT("%s: encountered fatal error, operation suspended\n",
993 adapter->name);
994}
995
996static int __devinit init_one(struct pci_dev *pdev,
997 const struct pci_device_id *ent)
998{
999 static int version_printed;
1000
1001 int i, err, pci_using_dac = 0;
1002 unsigned long mmio_start, mmio_len;
1003 const struct board_info *bi;
1004 struct adapter *adapter = NULL;
1005 struct port_info *pi;
1006
1007 if (!version_printed) {
1008 printk(KERN_INFO "%s - version %s\n", DRV_DESCRIPTION,
1009 DRV_VERSION);
1010 ++version_printed;
1011 }
1012
1013 err = pci_enable_device(pdev);
1014 if (err)
1015 return err;
1016
1017 if (!(pci_resource_flags(pdev, 0) & IORESOURCE_MEM)) {
1018 CH_ERR("%s: cannot find PCI device memory base address\n",
1019 pci_name(pdev));
1020 err = -ENODEV;
1021 goto out_disable_pdev;
1022 }
1023
1024 if (!pci_set_dma_mask(pdev, DMA_64BIT_MASK)) {
1025 pci_using_dac = 1;
1026
1027 if (pci_set_consistent_dma_mask(pdev, DMA_64BIT_MASK)) {
1028 CH_ERR("%s: unable to obtain 64-bit DMA for"
1029 "consistent allocations\n", pci_name(pdev));
1030 err = -ENODEV;
1031 goto out_disable_pdev;
1032 }
1033
1034 } else if ((err = pci_set_dma_mask(pdev, DMA_32BIT_MASK)) != 0) {
1035 CH_ERR("%s: no usable DMA configuration\n", pci_name(pdev));
1036 goto out_disable_pdev;
1037 }
1038
1039 err = pci_request_regions(pdev, DRV_NAME);
1040 if (err) {
1041 CH_ERR("%s: cannot obtain PCI resources\n", pci_name(pdev));
1042 goto out_disable_pdev;
1043 }
1044
1045 pci_set_master(pdev);
1046
1047 mmio_start = pci_resource_start(pdev, 0);
1048 mmio_len = pci_resource_len(pdev, 0);
1049 bi = t1_get_board_info(ent->driver_data);
1050
1051 for (i = 0; i < bi->port_number; ++i) {
1052 struct net_device *netdev;
1053
1054 netdev = alloc_etherdev(adapter ? 0 : sizeof(*adapter));
1055 if (!netdev) {
1056 err = -ENOMEM;
1057 goto out_free_dev;
1058 }
1059
1060 SET_MODULE_OWNER(netdev);
1061 SET_NETDEV_DEV(netdev, &pdev->dev);
1062
1063 if (!adapter) {
1064 adapter = netdev->priv;
1065 adapter->pdev = pdev;
1066 adapter->port[0].dev = netdev; /* so we don't leak it */
1067
1068 adapter->regs = ioremap(mmio_start, mmio_len);
1069 if (!adapter->regs) {
1070 CH_ERR("%s: cannot map device registers\n",
1071 pci_name(pdev));
1072 err = -ENOMEM;
1073 goto out_free_dev;
1074 }
1075
1076 if (t1_get_board_rev(adapter, bi, &adapter->params)) {
1077 err = -ENODEV; /* Can't handle this chip rev */
1078 goto out_free_dev;
1079 }
1080
1081 adapter->name = pci_name(pdev);
1082 adapter->msg_enable = dflt_msg_enable;
1083 adapter->mmio_len = mmio_len;
1084
1085 init_MUTEX(&adapter->mib_mutex);
1086 spin_lock_init(&adapter->tpi_lock);
1087 spin_lock_init(&adapter->work_lock);
1088 spin_lock_init(&adapter->async_lock);
1089
1090 INIT_WORK(&adapter->ext_intr_handler_task,
1091 ext_intr_task, adapter);
1092 INIT_WORK(&adapter->stats_update_task, mac_stats_task,
1093 adapter);
1094#ifdef work_struct
1095 init_timer(&adapter->stats_update_timer);
1096 adapter->stats_update_timer.function = mac_stats_timer;
1097 adapter->stats_update_timer.data =
1098 (unsigned long)adapter;
1099#endif
1100
1101 pci_set_drvdata(pdev, netdev);
1102 }
1103
1104 pi = &adapter->port[i];
1105 pi->dev = netdev;
1106 netif_carrier_off(netdev);
1107 netdev->irq = pdev->irq;
1108 netdev->if_port = i;
1109 netdev->mem_start = mmio_start;
1110 netdev->mem_end = mmio_start + mmio_len - 1;
1111 netdev->priv = adapter;
1112 netdev->features |= NETIF_F_SG | NETIF_F_IP_CSUM;
1113 netdev->features |= NETIF_F_LLTX;
1114
1115 adapter->flags |= RX_CSUM_ENABLED | TCP_CSUM_CAPABLE;
1116 if (pci_using_dac)
1117 netdev->features |= NETIF_F_HIGHDMA;
1118 if (vlan_tso_capable(adapter)) {
1119#if defined(CONFIG_VLAN_8021Q) || defined(CONFIG_VLAN_8021Q_MODULE)
1120 adapter->flags |= VLAN_ACCEL_CAPABLE;
1121 netdev->features |=
1122 NETIF_F_HW_VLAN_TX | NETIF_F_HW_VLAN_RX;
1123 netdev->vlan_rx_register = vlan_rx_register;
1124 netdev->vlan_rx_kill_vid = vlan_rx_kill_vid;
1125#endif
1126 adapter->flags |= TSO_CAPABLE;
1127 netdev->features |= NETIF_F_TSO;
1128 }
1129
1130 netdev->open = cxgb_open;
1131 netdev->stop = cxgb_close;
1132 netdev->hard_start_xmit = t1_start_xmit;
1133 netdev->hard_header_len += (adapter->flags & TSO_CAPABLE) ?
1134 sizeof(struct cpl_tx_pkt_lso) :
1135 sizeof(struct cpl_tx_pkt);
1136 netdev->get_stats = t1_get_stats;
1137 netdev->set_multicast_list = t1_set_rxmode;
1138 netdev->do_ioctl = t1_ioctl;
1139 netdev->change_mtu = t1_change_mtu;
1140 netdev->set_mac_address = t1_set_mac_addr;
1141#ifdef CONFIG_NET_POLL_CONTROLLER
1142 netdev->poll_controller = t1_netpoll;
1143#endif
1144 netdev->weight = 64;
1145
1146 SET_ETHTOOL_OPS(netdev, &t1_ethtool_ops);
1147 }
1148
1149 if (t1_init_sw_modules(adapter, bi) < 0) {
1150 err = -ENODEV;
1151 goto out_free_dev;
1152 }
1153
1154 /*
1155 * The card is now ready to go. If any errors occur during device
1156 * registration we do not fail the whole card but rather proceed only
1157 * with the ports we manage to register successfully. However we must
1158 * register at least one net device.
1159 */
1160 for (i = 0; i < bi->port_number; ++i) {
1161 err = register_netdev(adapter->port[i].dev);
1162 if (err)
1163 CH_WARN("%s: cannot register net device %s, skipping\n",
1164 pci_name(pdev), adapter->port[i].dev->name);
1165 else {
1166 /*
1167 * Change the name we use for messages to the name of
1168 * the first successfully registered interface.
1169 */
1170 if (!adapter->registered_device_map)
1171 adapter->name = adapter->port[i].dev->name;
1172
1173 __set_bit(i, &adapter->registered_device_map);
1174 }
1175 }
1176 if (!adapter->registered_device_map) {
1177 CH_ERR("%s: could not register any net devices\n",
1178 pci_name(pdev));
1179 goto out_release_adapter_res;
1180 }
1181
1182 printk(KERN_INFO "%s: %s (rev %d), %s %dMHz/%d-bit\n", adapter->name,
1183 bi->desc, adapter->params.chip_revision,
1184 adapter->params.pci.is_pcix ? "PCIX" : "PCI",
1185 adapter->params.pci.speed, adapter->params.pci.width);
1186 return 0;
1187
1188 out_release_adapter_res:
1189 t1_free_sw_modules(adapter);
1190 out_free_dev:
1191 if (adapter) {
1192 if (adapter->regs) iounmap(adapter->regs);
1193 for (i = bi->port_number - 1; i >= 0; --i)
1194 if (adapter->port[i].dev) {
1195 cxgb_proc_cleanup(adapter, proc_root_driver);
1196 kfree(adapter->port[i].dev);
1197 }
1198 }
1199 pci_release_regions(pdev);
1200 out_disable_pdev:
1201 pci_disable_device(pdev);
1202 pci_set_drvdata(pdev, NULL);
1203 return err;
1204}
1205
1206static inline void t1_sw_reset(struct pci_dev *pdev)
1207{
1208 pci_write_config_dword(pdev, A_PCICFG_PM_CSR, 3);
1209 pci_write_config_dword(pdev, A_PCICFG_PM_CSR, 0);
1210}
1211
1212static void __devexit remove_one(struct pci_dev *pdev)
1213{
1214 struct net_device *dev = pci_get_drvdata(pdev);
1215
1216 if (dev) {
1217 int i;
1218 struct adapter *adapter = dev->priv;
1219
1220 for_each_port(adapter, i)
1221 if (test_bit(i, &adapter->registered_device_map))
1222 unregister_netdev(adapter->port[i].dev);
1223
1224 t1_free_sw_modules(adapter);
1225 iounmap(adapter->regs);
1226 while (--i >= 0)
1227 if (adapter->port[i].dev) {
1228 cxgb_proc_cleanup(adapter, proc_root_driver);
1229 kfree(adapter->port[i].dev);
1230 }
1231 pci_release_regions(pdev);
1232 pci_disable_device(pdev);
1233 pci_set_drvdata(pdev, NULL);
1234 t1_sw_reset(pdev);
1235 }
1236}
1237
1238static struct pci_driver driver = {
1239 .name = DRV_NAME,
1240 .id_table = t1_pci_tbl,
1241 .probe = init_one,
1242 .remove = __devexit_p(remove_one),
1243};
1244
1245static int __init t1_init_module(void)
1246{
1247 return pci_module_init(&driver);
1248}
1249
1250static void __exit t1_cleanup_module(void)
1251{
1252 pci_unregister_driver(&driver);
1253}
1254
1255module_init(t1_init_module);
1256module_exit(t1_cleanup_module);
diff --git a/drivers/net/chelsio/elmer0.h b/drivers/net/chelsio/elmer0.h
new file mode 100644
index 000000000000..5590cb2dac19
--- /dev/null
+++ b/drivers/net/chelsio/elmer0.h
@@ -0,0 +1,151 @@
1/*****************************************************************************
2 * *
3 * File: elmer0.h *
4 * $Revision: 1.6 $ *
5 * $Date: 2005/06/21 22:49:43 $ *
6 * Description: *
7 * part of the Chelsio 10Gb Ethernet Driver. *
8 * *
9 * This program is free software; you can redistribute it and/or modify *
10 * it under the terms of the GNU General Public License, version 2, as *
11 * published by the Free Software Foundation. *
12 * *
13 * You should have received a copy of the GNU General Public License along *
14 * with this program; if not, write to the Free Software Foundation, Inc., *
15 * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
16 * *
17 * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED *
18 * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF *
19 * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. *
20 * *
21 * http://www.chelsio.com *
22 * *
23 * Copyright (c) 2003 - 2005 Chelsio Communications, Inc. *
24 * All rights reserved. *
25 * *
26 * Maintainers: maintainers@chelsio.com *
27 * *
28 * Authors: Dimitrios Michailidis <dm@chelsio.com> *
29 * Tina Yang <tainay@chelsio.com> *
30 * Felix Marti <felix@chelsio.com> *
31 * Scott Bardone <sbardone@chelsio.com> *
32 * Kurt Ottaway <kottaway@chelsio.com> *
33 * Frank DiMambro <frank@chelsio.com> *
34 * *
35 * History: *
36 * *
37 ****************************************************************************/
38
39#ifndef _CXGB_ELMER0_H_
40#define _CXGB_ELMER0_H_
41
42/* ELMER0 registers */
43#define A_ELMER0_VERSION 0x100000
44#define A_ELMER0_PHY_CFG 0x100004
45#define A_ELMER0_INT_ENABLE 0x100008
46#define A_ELMER0_INT_CAUSE 0x10000c
47#define A_ELMER0_GPI_CFG 0x100010
48#define A_ELMER0_GPI_STAT 0x100014
49#define A_ELMER0_GPO 0x100018
50#define A_ELMER0_PORT0_MI1_CFG 0x400000
51
52#define S_MI1_MDI_ENABLE 0
53#define V_MI1_MDI_ENABLE(x) ((x) << S_MI1_MDI_ENABLE)
54#define F_MI1_MDI_ENABLE V_MI1_MDI_ENABLE(1U)
55
56#define S_MI1_MDI_INVERT 1
57#define V_MI1_MDI_INVERT(x) ((x) << S_MI1_MDI_INVERT)
58#define F_MI1_MDI_INVERT V_MI1_MDI_INVERT(1U)
59
60#define S_MI1_PREAMBLE_ENABLE 2
61#define V_MI1_PREAMBLE_ENABLE(x) ((x) << S_MI1_PREAMBLE_ENABLE)
62#define F_MI1_PREAMBLE_ENABLE V_MI1_PREAMBLE_ENABLE(1U)
63
64#define S_MI1_SOF 3
65#define M_MI1_SOF 0x3
66#define V_MI1_SOF(x) ((x) << S_MI1_SOF)
67#define G_MI1_SOF(x) (((x) >> S_MI1_SOF) & M_MI1_SOF)
68
69#define S_MI1_CLK_DIV 5
70#define M_MI1_CLK_DIV 0xff
71#define V_MI1_CLK_DIV(x) ((x) << S_MI1_CLK_DIV)
72#define G_MI1_CLK_DIV(x) (((x) >> S_MI1_CLK_DIV) & M_MI1_CLK_DIV)
73
74#define A_ELMER0_PORT0_MI1_ADDR 0x400004
75
76#define S_MI1_REG_ADDR 0
77#define M_MI1_REG_ADDR 0x1f
78#define V_MI1_REG_ADDR(x) ((x) << S_MI1_REG_ADDR)
79#define G_MI1_REG_ADDR(x) (((x) >> S_MI1_REG_ADDR) & M_MI1_REG_ADDR)
80
81#define S_MI1_PHY_ADDR 5
82#define M_MI1_PHY_ADDR 0x1f
83#define V_MI1_PHY_ADDR(x) ((x) << S_MI1_PHY_ADDR)
84#define G_MI1_PHY_ADDR(x) (((x) >> S_MI1_PHY_ADDR) & M_MI1_PHY_ADDR)
85
86#define A_ELMER0_PORT0_MI1_DATA 0x400008
87
88#define S_MI1_DATA 0
89#define M_MI1_DATA 0xffff
90#define V_MI1_DATA(x) ((x) << S_MI1_DATA)
91#define G_MI1_DATA(x) (((x) >> S_MI1_DATA) & M_MI1_DATA)
92
93#define A_ELMER0_PORT0_MI1_OP 0x40000c
94
95#define S_MI1_OP 0
96#define M_MI1_OP 0x3
97#define V_MI1_OP(x) ((x) << S_MI1_OP)
98#define G_MI1_OP(x) (((x) >> S_MI1_OP) & M_MI1_OP)
99
100#define S_MI1_ADDR_AUTOINC 2
101#define V_MI1_ADDR_AUTOINC(x) ((x) << S_MI1_ADDR_AUTOINC)
102#define F_MI1_ADDR_AUTOINC V_MI1_ADDR_AUTOINC(1U)
103
104#define S_MI1_OP_BUSY 31
105#define V_MI1_OP_BUSY(x) ((x) << S_MI1_OP_BUSY)
106#define F_MI1_OP_BUSY V_MI1_OP_BUSY(1U)
107
108#define A_ELMER0_PORT1_MI1_CFG 0x500000
109#define A_ELMER0_PORT1_MI1_ADDR 0x500004
110#define A_ELMER0_PORT1_MI1_DATA 0x500008
111#define A_ELMER0_PORT1_MI1_OP 0x50000c
112#define A_ELMER0_PORT2_MI1_CFG 0x600000
113#define A_ELMER0_PORT2_MI1_ADDR 0x600004
114#define A_ELMER0_PORT2_MI1_DATA 0x600008
115#define A_ELMER0_PORT2_MI1_OP 0x60000c
116#define A_ELMER0_PORT3_MI1_CFG 0x700000
117#define A_ELMER0_PORT3_MI1_ADDR 0x700004
118#define A_ELMER0_PORT3_MI1_DATA 0x700008
119#define A_ELMER0_PORT3_MI1_OP 0x70000c
120
121/* Simple bit definition for GPI and GP0 registers. */
122#define ELMER0_GP_BIT0 0x0001
123#define ELMER0_GP_BIT1 0x0002
124#define ELMER0_GP_BIT2 0x0004
125#define ELMER0_GP_BIT3 0x0008
126#define ELMER0_GP_BIT4 0x0010
127#define ELMER0_GP_BIT5 0x0020
128#define ELMER0_GP_BIT6 0x0040
129#define ELMER0_GP_BIT7 0x0080
130#define ELMER0_GP_BIT8 0x0100
131#define ELMER0_GP_BIT9 0x0200
132#define ELMER0_GP_BIT10 0x0400
133#define ELMER0_GP_BIT11 0x0800
134#define ELMER0_GP_BIT12 0x1000
135#define ELMER0_GP_BIT13 0x2000
136#define ELMER0_GP_BIT14 0x4000
137#define ELMER0_GP_BIT15 0x8000
138#define ELMER0_GP_BIT16 0x10000
139#define ELMER0_GP_BIT17 0x20000
140#define ELMER0_GP_BIT18 0x40000
141#define ELMER0_GP_BIT19 0x80000
142
143#define MI1_OP_DIRECT_WRITE 1
144#define MI1_OP_DIRECT_READ 2
145
146#define MI1_OP_INDIRECT_ADDRESS 0
147#define MI1_OP_INDIRECT_WRITE 1
148#define MI1_OP_INDIRECT_READ_INC 2
149#define MI1_OP_INDIRECT_READ 3
150
151#endif /* _CXGB_ELMER0_H_ */
diff --git a/drivers/net/chelsio/espi.c b/drivers/net/chelsio/espi.c
new file mode 100644
index 000000000000..230642571c92
--- /dev/null
+++ b/drivers/net/chelsio/espi.c
@@ -0,0 +1,346 @@
1/*****************************************************************************
2 * *
3 * File: espi.c *
4 * $Revision: 1.14 $ *
5 * $Date: 2005/05/14 00:59:32 $ *
6 * Description: *
7 * Ethernet SPI functionality. *
8 * part of the Chelsio 10Gb Ethernet Driver. *
9 * *
10 * This program is free software; you can redistribute it and/or modify *
11 * it under the terms of the GNU General Public License, version 2, as *
12 * published by the Free Software Foundation. *
13 * *
14 * You should have received a copy of the GNU General Public License along *
15 * with this program; if not, write to the Free Software Foundation, Inc., *
16 * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
17 * *
18 * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED *
19 * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF *
20 * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. *
21 * *
22 * http://www.chelsio.com *
23 * *
24 * Copyright (c) 2003 - 2005 Chelsio Communications, Inc. *
25 * All rights reserved. *
26 * *
27 * Maintainers: maintainers@chelsio.com *
28 * *
29 * Authors: Dimitrios Michailidis <dm@chelsio.com> *
30 * Tina Yang <tainay@chelsio.com> *
31 * Felix Marti <felix@chelsio.com> *
32 * Scott Bardone <sbardone@chelsio.com> *
33 * Kurt Ottaway <kottaway@chelsio.com> *
34 * Frank DiMambro <frank@chelsio.com> *
35 * *
36 * History: *
37 * *
38 ****************************************************************************/
39
40#include "common.h"
41#include "regs.h"
42#include "espi.h"
43
44struct peespi {
45 adapter_t *adapter;
46 struct espi_intr_counts intr_cnt;
47 u32 misc_ctrl;
48 spinlock_t lock;
49};
50
51#define ESPI_INTR_MASK (F_DIP4ERR | F_RXDROP | F_TXDROP | F_RXOVERFLOW | \
52 F_RAMPARITYERR | F_DIP2PARITYERR)
53#define MON_MASK (V_MONITORED_PORT_NUM(3) | F_MONITORED_DIRECTION \
54 | F_MONITORED_INTERFACE)
55
56#define TRICN_CNFG 14
57#define TRICN_CMD_READ 0x11
58#define TRICN_CMD_WRITE 0x21
59#define TRICN_CMD_ATTEMPTS 10
60
61static int tricn_write(adapter_t *adapter, int bundle_addr, int module_addr,
62 int ch_addr, int reg_offset, u32 wr_data)
63{
64 int busy, attempts = TRICN_CMD_ATTEMPTS;
65
66 writel(V_WRITE_DATA(wr_data) |
67 V_REGISTER_OFFSET(reg_offset) |
68 V_CHANNEL_ADDR(ch_addr) | V_MODULE_ADDR(module_addr) |
69 V_BUNDLE_ADDR(bundle_addr) |
70 V_SPI4_COMMAND(TRICN_CMD_WRITE),
71 adapter->regs + A_ESPI_CMD_ADDR);
72 writel(0, adapter->regs + A_ESPI_GOSTAT);
73
74 do {
75 busy = readl(adapter->regs + A_ESPI_GOSTAT) & F_ESPI_CMD_BUSY;
76 } while (busy && --attempts);
77
78 if (busy)
79 CH_ERR("%s: TRICN write timed out\n", adapter->name);
80
81 return busy;
82}
83
84/* 1. Deassert rx_reset_core. */
85/* 2. Program TRICN_CNFG registers. */
86/* 3. Deassert rx_reset_link */
87static int tricn_init(adapter_t *adapter)
88{
89 int i = 0;
90 int sme = 1;
91 int stat = 0;
92 int timeout = 0;
93 int is_ready = 0;
94 int dynamic_deskew = 0;
95
96 if (dynamic_deskew)
97 sme = 0;
98
99
100 /* 1 */
101 timeout=1000;
102 do {
103 stat = readl(adapter->regs + A_ESPI_RX_RESET);
104 is_ready = (stat & 0x4);
105 timeout--;
106 udelay(5);
107 } while (!is_ready || (timeout==0));
108 writel(0x2, adapter->regs + A_ESPI_RX_RESET);
109 if (timeout==0)
110 {
111 CH_ERR("ESPI : ERROR : Timeout tricn_init() \n");
112 t1_fatal_err(adapter);
113 }
114
115 /* 2 */
116 if (sme) {
117 tricn_write(adapter, 0, 0, 0, TRICN_CNFG, 0x81);
118 tricn_write(adapter, 0, 1, 0, TRICN_CNFG, 0x81);
119 tricn_write(adapter, 0, 2, 0, TRICN_CNFG, 0x81);
120 }
121 for (i=1; i<= 8; i++) tricn_write(adapter, 0, 0, i, TRICN_CNFG, 0xf1);
122 for (i=1; i<= 2; i++) tricn_write(adapter, 0, 1, i, TRICN_CNFG, 0xf1);
123 for (i=1; i<= 3; i++) tricn_write(adapter, 0, 2, i, TRICN_CNFG, 0xe1);
124 for (i=4; i<= 4; i++) tricn_write(adapter, 0, 2, i, TRICN_CNFG, 0xf1);
125 for (i=5; i<= 5; i++) tricn_write(adapter, 0, 2, i, TRICN_CNFG, 0xe1);
126 for (i=6; i<= 6; i++) tricn_write(adapter, 0, 2, i, TRICN_CNFG, 0xf1);
127 for (i=7; i<= 7; i++) tricn_write(adapter, 0, 2, i, TRICN_CNFG, 0x80);
128 for (i=8; i<= 8; i++) tricn_write(adapter, 0, 2, i, TRICN_CNFG, 0xf1);
129
130 /* 3 */
131 writel(0x3, adapter->regs + A_ESPI_RX_RESET);
132
133 return 0;
134}
135
136void t1_espi_intr_enable(struct peespi *espi)
137{
138 u32 enable, pl_intr = readl(espi->adapter->regs + A_PL_ENABLE);
139
140 /*
141 * Cannot enable ESPI interrupts on T1B because HW asserts the
142 * interrupt incorrectly, namely the driver gets ESPI interrupts
143 * but no data is actually dropped (can verify this reading the ESPI
144 * drop registers). Also, once the ESPI interrupt is asserted it
145 * cannot be cleared (HW bug).
146 */
147 enable = t1_is_T1B(espi->adapter) ? 0 : ESPI_INTR_MASK;
148 writel(enable, espi->adapter->regs + A_ESPI_INTR_ENABLE);
149 writel(pl_intr | F_PL_INTR_ESPI, espi->adapter->regs + A_PL_ENABLE);
150}
151
152void t1_espi_intr_clear(struct peespi *espi)
153{
154 writel(0xffffffff, espi->adapter->regs + A_ESPI_INTR_STATUS);
155 writel(F_PL_INTR_ESPI, espi->adapter->regs + A_PL_CAUSE);
156}
157
158void t1_espi_intr_disable(struct peespi *espi)
159{
160 u32 pl_intr = readl(espi->adapter->regs + A_PL_ENABLE);
161
162 writel(0, espi->adapter->regs + A_ESPI_INTR_ENABLE);
163 writel(pl_intr & ~F_PL_INTR_ESPI, espi->adapter->regs + A_PL_ENABLE);
164}
165
166int t1_espi_intr_handler(struct peespi *espi)
167{
168 u32 cnt;
169 u32 status = readl(espi->adapter->regs + A_ESPI_INTR_STATUS);
170
171 if (status & F_DIP4ERR)
172 espi->intr_cnt.DIP4_err++;
173 if (status & F_RXDROP)
174 espi->intr_cnt.rx_drops++;
175 if (status & F_TXDROP)
176 espi->intr_cnt.tx_drops++;
177 if (status & F_RXOVERFLOW)
178 espi->intr_cnt.rx_ovflw++;
179 if (status & F_RAMPARITYERR)
180 espi->intr_cnt.parity_err++;
181 if (status & F_DIP2PARITYERR) {
182 espi->intr_cnt.DIP2_parity_err++;
183
184 /*
185 * Must read the error count to clear the interrupt
186 * that it causes.
187 */
188 cnt = readl(espi->adapter->regs + A_ESPI_DIP2_ERR_COUNT);
189 }
190
191 /*
192 * For T1B we need to write 1 to clear ESPI interrupts. For T2+ we
193 * write the status as is.
194 */
195 if (status && t1_is_T1B(espi->adapter))
196 status = 1;
197 writel(status, espi->adapter->regs + A_ESPI_INTR_STATUS);
198 return 0;
199}
200
201const struct espi_intr_counts *t1_espi_get_intr_counts(struct peespi *espi)
202{
203 return &espi->intr_cnt;
204}
205
206static void espi_setup_for_pm3393(adapter_t *adapter)
207{
208 u32 wmark = t1_is_T1B(adapter) ? 0x4000 : 0x3200;
209
210 writel(0x1f4, adapter->regs + A_ESPI_SCH_TOKEN0);
211 writel(0x1f4, adapter->regs + A_ESPI_SCH_TOKEN1);
212 writel(0x1f4, adapter->regs + A_ESPI_SCH_TOKEN2);
213 writel(0x1f4, adapter->regs + A_ESPI_SCH_TOKEN3);
214 writel(0x100, adapter->regs + A_ESPI_RX_FIFO_ALMOST_EMPTY_WATERMARK);
215 writel(wmark, adapter->regs + A_ESPI_RX_FIFO_ALMOST_FULL_WATERMARK);
216 writel(3, adapter->regs + A_ESPI_CALENDAR_LENGTH);
217 writel(0x08000008, adapter->regs + A_ESPI_TRAIN);
218 writel(V_RX_NPORTS(1) | V_TX_NPORTS(1), adapter->regs + A_PORT_CONFIG);
219}
220
221/* T2 Init part -- */
222/* 1. Set T_ESPI_MISCCTRL_ADDR */
223/* 2. Init ESPI registers. */
224/* 3. Init TriCN Hard Macro */
225int t1_espi_init(struct peespi *espi, int mac_type, int nports)
226{
227 u32 cnt;
228
229 u32 status_enable_extra = 0;
230 adapter_t *adapter = espi->adapter;
231 u32 status, burstval = 0x800100;
232
233 /* Disable ESPI training. MACs that can handle it enable it below. */
234 writel(0, adapter->regs + A_ESPI_TRAIN);
235
236 if (is_T2(adapter)) {
237 writel(V_OUT_OF_SYNC_COUNT(4) |
238 V_DIP2_PARITY_ERR_THRES(3) |
239 V_DIP4_THRES(1), adapter->regs + A_ESPI_MISC_CONTROL);
240 if (nports == 4) {
241 /* T204: maxburst1 = 0x40, maxburst2 = 0x20 */
242 burstval = 0x200040;
243 }
244 }
245 writel(burstval, adapter->regs + A_ESPI_MAXBURST1_MAXBURST2);
246
247 switch (mac_type) {
248 case CHBT_MAC_PM3393:
249 espi_setup_for_pm3393(adapter);
250 break;
251 default:
252 return -1;
253 }
254
255 /*
256 * Make sure any pending interrupts from the SPI are
257 * Cleared before enabling the interrupt.
258 */
259 writel(ESPI_INTR_MASK, espi->adapter->regs + A_ESPI_INTR_ENABLE);
260 status = readl(espi->adapter->regs + A_ESPI_INTR_STATUS);
261 if (status & F_DIP2PARITYERR) {
262 cnt = readl(espi->adapter->regs + A_ESPI_DIP2_ERR_COUNT);
263 }
264
265 /*
266 * For T1B we need to write 1 to clear ESPI interrupts. For T2+ we
267 * write the status as is.
268 */
269 if (status && t1_is_T1B(espi->adapter))
270 status = 1;
271 writel(status, espi->adapter->regs + A_ESPI_INTR_STATUS);
272
273 writel(status_enable_extra | F_RXSTATUSENABLE,
274 adapter->regs + A_ESPI_FIFO_STATUS_ENABLE);
275
276 if (is_T2(adapter)) {
277 tricn_init(adapter);
278 /*
279 * Always position the control at the 1st port egress IN
280 * (sop,eop) counter to reduce PIOs for T/N210 workaround.
281 */
282 espi->misc_ctrl = (readl(adapter->regs + A_ESPI_MISC_CONTROL)
283 & ~MON_MASK) | (F_MONITORED_DIRECTION
284 | F_MONITORED_INTERFACE);
285 writel(espi->misc_ctrl, adapter->regs + A_ESPI_MISC_CONTROL);
286 spin_lock_init(&espi->lock);
287 }
288
289 return 0;
290}
291
292void t1_espi_destroy(struct peespi *espi)
293{
294 kfree(espi);
295}
296
297struct peespi *t1_espi_create(adapter_t *adapter)
298{
299 struct peespi *espi = kmalloc(sizeof(*espi), GFP_KERNEL);
300
301 memset(espi, 0, sizeof(*espi));
302
303 if (espi)
304 espi->adapter = adapter;
305 return espi;
306}
307
308void t1_espi_set_misc_ctrl(adapter_t *adapter, u32 val)
309{
310 struct peespi *espi = adapter->espi;
311
312 if (!is_T2(adapter))
313 return;
314 spin_lock(&espi->lock);
315 espi->misc_ctrl = (val & ~MON_MASK) |
316 (espi->misc_ctrl & MON_MASK);
317 writel(espi->misc_ctrl, adapter->regs + A_ESPI_MISC_CONTROL);
318 spin_unlock(&espi->lock);
319}
320
321u32 t1_espi_get_mon(adapter_t *adapter, u32 addr, u8 wait)
322{
323 u32 sel;
324
325 struct peespi *espi = adapter->espi;
326
327 if (!is_T2(adapter))
328 return 0;
329 sel = V_MONITORED_PORT_NUM((addr & 0x3c) >> 2);
330 if (!wait) {
331 if (!spin_trylock(&espi->lock))
332 return 0;
333 }
334 else
335 spin_lock(&espi->lock);
336 if ((sel != (espi->misc_ctrl & MON_MASK))) {
337 writel(((espi->misc_ctrl & ~MON_MASK) | sel),
338 adapter->regs + A_ESPI_MISC_CONTROL);
339 sel = readl(adapter->regs + A_ESPI_SCH_TOKEN3);
340 writel(espi->misc_ctrl, adapter->regs + A_ESPI_MISC_CONTROL);
341 }
342 else
343 sel = readl(adapter->regs + A_ESPI_SCH_TOKEN3);
344 spin_unlock(&espi->lock);
345 return sel;
346}
diff --git a/drivers/net/chelsio/espi.h b/drivers/net/chelsio/espi.h
new file mode 100644
index 000000000000..c90e37f8457c
--- /dev/null
+++ b/drivers/net/chelsio/espi.h
@@ -0,0 +1,68 @@
1/*****************************************************************************
2 * *
3 * File: espi.h *
4 * $Revision: 1.7 $ *
5 * $Date: 2005/06/21 18:29:47 $ *
6 * Description: *
7 * part of the Chelsio 10Gb Ethernet Driver. *
8 * *
9 * This program is free software; you can redistribute it and/or modify *
10 * it under the terms of the GNU General Public License, version 2, as *
11 * published by the Free Software Foundation. *
12 * *
13 * You should have received a copy of the GNU General Public License along *
14 * with this program; if not, write to the Free Software Foundation, Inc., *
15 * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
16 * *
17 * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED *
18 * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF *
19 * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. *
20 * *
21 * http://www.chelsio.com *
22 * *
23 * Copyright (c) 2003 - 2005 Chelsio Communications, Inc. *
24 * All rights reserved. *
25 * *
26 * Maintainers: maintainers@chelsio.com *
27 * *
28 * Authors: Dimitrios Michailidis <dm@chelsio.com> *
29 * Tina Yang <tainay@chelsio.com> *
30 * Felix Marti <felix@chelsio.com> *
31 * Scott Bardone <sbardone@chelsio.com> *
32 * Kurt Ottaway <kottaway@chelsio.com> *
33 * Frank DiMambro <frank@chelsio.com> *
34 * *
35 * History: *
36 * *
37 ****************************************************************************/
38
39#ifndef _CXGB_ESPI_H_
40#define _CXGB_ESPI_H_
41
42#include "common.h"
43
44struct espi_intr_counts {
45 unsigned int DIP4_err;
46 unsigned int rx_drops;
47 unsigned int tx_drops;
48 unsigned int rx_ovflw;
49 unsigned int parity_err;
50 unsigned int DIP2_parity_err;
51};
52
53struct peespi;
54
55struct peespi *t1_espi_create(adapter_t *adapter);
56void t1_espi_destroy(struct peespi *espi);
57int t1_espi_init(struct peespi *espi, int mac_type, int nports);
58
59void t1_espi_intr_enable(struct peespi *);
60void t1_espi_intr_clear(struct peespi *);
61void t1_espi_intr_disable(struct peespi *);
62int t1_espi_intr_handler(struct peespi *);
63const struct espi_intr_counts *t1_espi_get_intr_counts(struct peespi *espi);
64
65void t1_espi_set_misc_ctrl(adapter_t *adapter, u32 val);
66u32 t1_espi_get_mon(adapter_t *adapter, u32 addr, u8 wait);
67
68#endif /* _CXGB_ESPI_H_ */
diff --git a/drivers/net/chelsio/gmac.h b/drivers/net/chelsio/gmac.h
new file mode 100644
index 000000000000..746b0eeea964
--- /dev/null
+++ b/drivers/net/chelsio/gmac.h
@@ -0,0 +1,134 @@
1/*****************************************************************************
2 * *
3 * File: gmac.h *
4 * $Revision: 1.6 $ *
5 * $Date: 2005/06/21 18:29:47 $ *
6 * Description: *
7 * Generic MAC functionality. *
8 * part of the Chelsio 10Gb Ethernet Driver. *
9 * *
10 * This program is free software; you can redistribute it and/or modify *
11 * it under the terms of the GNU General Public License, version 2, as *
12 * published by the Free Software Foundation. *
13 * *
14 * You should have received a copy of the GNU General Public License along *
15 * with this program; if not, write to the Free Software Foundation, Inc., *
16 * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
17 * *
18 * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED *
19 * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF *
20 * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. *
21 * *
22 * http://www.chelsio.com *
23 * *
24 * Copyright (c) 2003 - 2005 Chelsio Communications, Inc. *
25 * All rights reserved. *
26 * *
27 * Maintainers: maintainers@chelsio.com *
28 * *
29 * Authors: Dimitrios Michailidis <dm@chelsio.com> *
30 * Tina Yang <tainay@chelsio.com> *
31 * Felix Marti <felix@chelsio.com> *
32 * Scott Bardone <sbardone@chelsio.com> *
33 * Kurt Ottaway <kottaway@chelsio.com> *
34 * Frank DiMambro <frank@chelsio.com> *
35 * *
36 * History: *
37 * *
38 ****************************************************************************/
39
40#ifndef _CXGB_GMAC_H_
41#define _CXGB_GMAC_H_
42
43#include "common.h"
44
45enum { MAC_STATS_UPDATE_FAST, MAC_STATS_UPDATE_FULL };
46enum { MAC_DIRECTION_RX = 1, MAC_DIRECTION_TX = 2 };
47
48struct cmac_statistics {
49 /* Transmit */
50 u64 TxOctetsOK;
51 u64 TxOctetsBad;
52 u64 TxUnicastFramesOK;
53 u64 TxMulticastFramesOK;
54 u64 TxBroadcastFramesOK;
55 u64 TxPauseFrames;
56 u64 TxFramesWithDeferredXmissions;
57 u64 TxLateCollisions;
58 u64 TxTotalCollisions;
59 u64 TxFramesAbortedDueToXSCollisions;
60 u64 TxUnderrun;
61 u64 TxLengthErrors;
62 u64 TxInternalMACXmitError;
63 u64 TxFramesWithExcessiveDeferral;
64 u64 TxFCSErrors;
65
66 /* Receive */
67 u64 RxOctetsOK;
68 u64 RxOctetsBad;
69 u64 RxUnicastFramesOK;
70 u64 RxMulticastFramesOK;
71 u64 RxBroadcastFramesOK;
72 u64 RxPauseFrames;
73 u64 RxFCSErrors;
74 u64 RxAlignErrors;
75 u64 RxSymbolErrors;
76 u64 RxDataErrors;
77 u64 RxSequenceErrors;
78 u64 RxRuntErrors;
79 u64 RxJabberErrors;
80 u64 RxInternalMACRcvError;
81 u64 RxInRangeLengthErrors;
82 u64 RxOutOfRangeLengthField;
83 u64 RxFrameTooLongErrors;
84};
85
86struct cmac_ops {
87 void (*destroy)(struct cmac *);
88 int (*reset)(struct cmac *);
89 int (*interrupt_enable)(struct cmac *);
90 int (*interrupt_disable)(struct cmac *);
91 int (*interrupt_clear)(struct cmac *);
92 int (*interrupt_handler)(struct cmac *);
93
94 int (*enable)(struct cmac *, int);
95 int (*disable)(struct cmac *, int);
96
97 int (*loopback_enable)(struct cmac *);
98 int (*loopback_disable)(struct cmac *);
99
100 int (*set_mtu)(struct cmac *, int mtu);
101 int (*set_rx_mode)(struct cmac *, struct t1_rx_mode *rm);
102
103 int (*set_speed_duplex_fc)(struct cmac *, int speed, int duplex, int fc);
104 int (*get_speed_duplex_fc)(struct cmac *, int *speed, int *duplex,
105 int *fc);
106
107 const struct cmac_statistics *(*statistics_update)(struct cmac *, int);
108
109 int (*macaddress_get)(struct cmac *, u8 mac_addr[6]);
110 int (*macaddress_set)(struct cmac *, u8 mac_addr[6]);
111};
112
113typedef struct _cmac_instance cmac_instance;
114
115struct cmac {
116 struct cmac_statistics stats;
117 adapter_t *adapter;
118 struct cmac_ops *ops;
119 cmac_instance *instance;
120};
121
122struct gmac {
123 unsigned int stats_update_period;
124 struct cmac *(*create)(adapter_t *adapter, int index);
125 int (*reset)(adapter_t *);
126};
127
128extern struct gmac t1_pm3393_ops;
129extern struct gmac t1_chelsio_mac_ops;
130extern struct gmac t1_vsc7321_ops;
131extern struct gmac t1_ixf1010_ops;
132extern struct gmac t1_dummy_mac_ops;
133
134#endif /* _CXGB_GMAC_H_ */
diff --git a/drivers/net/chelsio/mv88x201x.c b/drivers/net/chelsio/mv88x201x.c
new file mode 100644
index 000000000000..db5034282782
--- /dev/null
+++ b/drivers/net/chelsio/mv88x201x.c
@@ -0,0 +1,252 @@
1/*****************************************************************************
2 * *
3 * File: mv88x201x.c *
4 * $Revision: 1.12 $ *
5 * $Date: 2005/04/15 19:27:14 $ *
6 * Description: *
7 * Marvell PHY (mv88x201x) functionality. *
8 * part of the Chelsio 10Gb Ethernet Driver. *
9 * *
10 * This program is free software; you can redistribute it and/or modify *
11 * it under the terms of the GNU General Public License, version 2, as *
12 * published by the Free Software Foundation. *
13 * *
14 * You should have received a copy of the GNU General Public License along *
15 * with this program; if not, write to the Free Software Foundation, Inc., *
16 * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
17 * *
18 * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED *
19 * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF *
20 * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. *
21 * *
22 * http://www.chelsio.com *
23 * *
24 * Copyright (c) 2003 - 2005 Chelsio Communications, Inc. *
25 * All rights reserved. *
26 * *
27 * Maintainers: maintainers@chelsio.com *
28 * *
29 * Authors: Dimitrios Michailidis <dm@chelsio.com> *
30 * Tina Yang <tainay@chelsio.com> *
31 * Felix Marti <felix@chelsio.com> *
32 * Scott Bardone <sbardone@chelsio.com> *
33 * Kurt Ottaway <kottaway@chelsio.com> *
34 * Frank DiMambro <frank@chelsio.com> *
35 * *
36 * History: *
37 * *
38 ****************************************************************************/
39
40#include "cphy.h"
41#include "elmer0.h"
42
43/*
44 * The 88x2010 Rev C. requires some link status registers * to be read
45 * twice in order to get the right values. Future * revisions will fix
46 * this problem and then this macro * can disappear.
47 */
48#define MV88x2010_LINK_STATUS_BUGS 1
49
50static int led_init(struct cphy *cphy)
51{
52 /* Setup the LED registers so we can turn on/off.
53 * Writing these bits maps control to another
54 * register. mmd(0x1) addr(0x7)
55 */
56 mdio_write(cphy, 0x3, 0x8304, 0xdddd);
57 return 0;
58}
59
60static int led_link(struct cphy *cphy, u32 do_enable)
61{
62 u32 led = 0;
63#define LINK_ENABLE_BIT 0x1
64
65 mdio_read(cphy, 0x1, 0x7, &led);
66
67 if (do_enable & LINK_ENABLE_BIT) {
68 led |= LINK_ENABLE_BIT;
69 mdio_write(cphy, 0x1, 0x7, led);
70 } else {
71 led &= ~LINK_ENABLE_BIT;
72 mdio_write(cphy, 0x1, 0x7, led);
73 }
74 return 0;
75}
76
77/* Port Reset */
78static int mv88x201x_reset(struct cphy *cphy, int wait)
79{
80 /* This can be done through registers. It is not required since
81 * a full chip reset is used.
82 */
83 return 0;
84}
85
86static int mv88x201x_interrupt_enable(struct cphy *cphy)
87{
88 u32 elmer;
89
90 /* Enable PHY LASI interrupts. */
91 mdio_write(cphy, 0x1, 0x9002, 0x1);
92
93 /* Enable Marvell interrupts through Elmer0. */
94 t1_tpi_read(cphy->adapter, A_ELMER0_INT_ENABLE, &elmer);
95 elmer |= ELMER0_GP_BIT6;
96 t1_tpi_write(cphy->adapter, A_ELMER0_INT_ENABLE, elmer);
97 return 0;
98}
99
100static int mv88x201x_interrupt_disable(struct cphy *cphy)
101{
102 u32 elmer;
103
104 /* Disable PHY LASI interrupts. */
105 mdio_write(cphy, 0x1, 0x9002, 0x0);
106
107 /* Disable Marvell interrupts through Elmer0. */
108 t1_tpi_read(cphy->adapter, A_ELMER0_INT_ENABLE, &elmer);
109 elmer &= ~ELMER0_GP_BIT6;
110 t1_tpi_write(cphy->adapter, A_ELMER0_INT_ENABLE, elmer);
111 return 0;
112}
113
114static int mv88x201x_interrupt_clear(struct cphy *cphy)
115{
116 u32 elmer;
117 u32 val;
118
119#ifdef MV88x2010_LINK_STATUS_BUGS
120 /* Required to read twice before clear takes affect. */
121 mdio_read(cphy, 0x1, 0x9003, &val);
122 mdio_read(cphy, 0x1, 0x9004, &val);
123 mdio_read(cphy, 0x1, 0x9005, &val);
124
125 /* Read this register after the others above it else
126 * the register doesn't clear correctly.
127 */
128 mdio_read(cphy, 0x1, 0x1, &val);
129#endif
130
131 /* Clear link status. */
132 mdio_read(cphy, 0x1, 0x1, &val);
133 /* Clear PHY LASI interrupts. */
134 mdio_read(cphy, 0x1, 0x9005, &val);
135
136#ifdef MV88x2010_LINK_STATUS_BUGS
137 /* Do it again. */
138 mdio_read(cphy, 0x1, 0x9003, &val);
139 mdio_read(cphy, 0x1, 0x9004, &val);
140#endif
141
142 /* Clear Marvell interrupts through Elmer0. */
143 t1_tpi_read(cphy->adapter, A_ELMER0_INT_CAUSE, &elmer);
144 elmer |= ELMER0_GP_BIT6;
145 t1_tpi_write(cphy->adapter, A_ELMER0_INT_CAUSE, elmer);
146 return 0;
147}
148
149static int mv88x201x_interrupt_handler(struct cphy *cphy)
150{
151 /* Clear interrupts */
152 mv88x201x_interrupt_clear(cphy);
153
154 /* We have only enabled link change interrupts and so
155 * cphy_cause must be a link change interrupt.
156 */
157 return cphy_cause_link_change;
158}
159
160static int mv88x201x_set_loopback(struct cphy *cphy, int on)
161{
162 return 0;
163}
164
165static int mv88x201x_get_link_status(struct cphy *cphy, int *link_ok,
166 int *speed, int *duplex, int *fc)
167{
168 u32 val = 0;
169#define LINK_STATUS_BIT 0x4
170
171 if (link_ok) {
172 /* Read link status. */
173 mdio_read(cphy, 0x1, 0x1, &val);
174 val &= LINK_STATUS_BIT;
175 *link_ok = (val == LINK_STATUS_BIT);
176 /* Turn on/off Link LED */
177 led_link(cphy, *link_ok);
178 }
179 if (speed)
180 *speed = SPEED_10000;
181 if (duplex)
182 *duplex = DUPLEX_FULL;
183 if (fc)
184 *fc = PAUSE_RX | PAUSE_TX;
185 return 0;
186}
187
188static void mv88x201x_destroy(struct cphy *cphy)
189{
190 kfree(cphy);
191}
192
193static struct cphy_ops mv88x201x_ops = {
194 .destroy = mv88x201x_destroy,
195 .reset = mv88x201x_reset,
196 .interrupt_enable = mv88x201x_interrupt_enable,
197 .interrupt_disable = mv88x201x_interrupt_disable,
198 .interrupt_clear = mv88x201x_interrupt_clear,
199 .interrupt_handler = mv88x201x_interrupt_handler,
200 .get_link_status = mv88x201x_get_link_status,
201 .set_loopback = mv88x201x_set_loopback,
202};
203
204static struct cphy *mv88x201x_phy_create(adapter_t *adapter, int phy_addr,
205 struct mdio_ops *mdio_ops)
206{
207 u32 val;
208 struct cphy *cphy = kmalloc(sizeof(*cphy), GFP_KERNEL);
209
210 if (!cphy)
211 return NULL;
212 memset(cphy, 0, sizeof(*cphy));
213 cphy_init(cphy, adapter, phy_addr, &mv88x201x_ops, mdio_ops);
214
215 /* Commands the PHY to enable XFP's clock. */
216 mdio_read(cphy, 0x3, 0x8300, &val);
217 mdio_write(cphy, 0x3, 0x8300, val | 1);
218
219 /* Clear link status. Required because of a bug in the PHY. */
220 mdio_read(cphy, 0x1, 0x8, &val);
221 mdio_read(cphy, 0x3, 0x8, &val);
222
223 /* Allows for Link,Ack LED turn on/off */
224 led_init(cphy);
225 return cphy;
226}
227
228/* Chip Reset */
229static int mv88x201x_phy_reset(adapter_t *adapter)
230{
231 u32 val;
232
233 t1_tpi_read(adapter, A_ELMER0_GPO, &val);
234 val &= ~4;
235 t1_tpi_write(adapter, A_ELMER0_GPO, val);
236 msleep(100);
237
238 t1_tpi_write(adapter, A_ELMER0_GPO, val | 4);
239 msleep(1000);
240
241 /* Now lets enable the Laser. Delay 100us */
242 t1_tpi_read(adapter, A_ELMER0_GPO, &val);
243 val |= 0x8000;
244 t1_tpi_write(adapter, A_ELMER0_GPO, val);
245 udelay(100);
246 return 0;
247}
248
249struct gphy t1_mv88x201x_ops = {
250 mv88x201x_phy_create,
251 mv88x201x_phy_reset
252};
diff --git a/drivers/net/chelsio/pm3393.c b/drivers/net/chelsio/pm3393.c
new file mode 100644
index 000000000000..04a1404fc65e
--- /dev/null
+++ b/drivers/net/chelsio/pm3393.c
@@ -0,0 +1,826 @@
1/*****************************************************************************
2 * *
3 * File: pm3393.c *
4 * $Revision: 1.16 $ *
5 * $Date: 2005/05/14 00:59:32 $ *
6 * Description: *
7 * PMC/SIERRA (pm3393) MAC-PHY functionality. *
8 * part of the Chelsio 10Gb Ethernet Driver. *
9 * *
10 * This program is free software; you can redistribute it and/or modify *
11 * it under the terms of the GNU General Public License, version 2, as *
12 * published by the Free Software Foundation. *
13 * *
14 * You should have received a copy of the GNU General Public License along *
15 * with this program; if not, write to the Free Software Foundation, Inc., *
16 * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
17 * *
18 * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED *
19 * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF *
20 * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. *
21 * *
22 * http://www.chelsio.com *
23 * *
24 * Copyright (c) 2003 - 2005 Chelsio Communications, Inc. *
25 * All rights reserved. *
26 * *
27 * Maintainers: maintainers@chelsio.com *
28 * *
29 * Authors: Dimitrios Michailidis <dm@chelsio.com> *
30 * Tina Yang <tainay@chelsio.com> *
31 * Felix Marti <felix@chelsio.com> *
32 * Scott Bardone <sbardone@chelsio.com> *
33 * Kurt Ottaway <kottaway@chelsio.com> *
34 * Frank DiMambro <frank@chelsio.com> *
35 * *
36 * History: *
37 * *
38 ****************************************************************************/
39
40#include "common.h"
41#include "regs.h"
42#include "gmac.h"
43#include "elmer0.h"
44#include "suni1x10gexp_regs.h"
45
46/* 802.3ae 10Gb/s MDIO Manageable Device(MMD)
47 */
48enum {
49 MMD_RESERVED,
50 MMD_PMAPMD,
51 MMD_WIS,
52 MMD_PCS,
53 MMD_PHY_XGXS, /* XGMII Extender Sublayer */
54 MMD_DTE_XGXS,
55};
56
57enum {
58 PHY_XGXS_CTRL_1,
59 PHY_XGXS_STATUS_1
60};
61
62#define OFFSET(REG_ADDR) (REG_ADDR << 2)
63
64/* Max frame size PM3393 can handle. Includes Ethernet header and CRC. */
65#define MAX_FRAME_SIZE 9600
66
67#define IPG 12
68#define TXXG_CONF1_VAL ((IPG << SUNI1x10GEXP_BITOFF_TXXG_IPGT) | \
69 SUNI1x10GEXP_BITMSK_TXXG_32BIT_ALIGN | SUNI1x10GEXP_BITMSK_TXXG_CRCEN | \
70 SUNI1x10GEXP_BITMSK_TXXG_PADEN)
71#define RXXG_CONF1_VAL (SUNI1x10GEXP_BITMSK_RXXG_PUREP | 0x14 | \
72 SUNI1x10GEXP_BITMSK_RXXG_FLCHK | SUNI1x10GEXP_BITMSK_RXXG_CRC_STRIP)
73
74/* Update statistics every 15 minutes */
75#define STATS_TICK_SECS (15 * 60)
76
77enum { /* RMON registers */
78 RxOctetsReceivedOK = SUNI1x10GEXP_REG_MSTAT_COUNTER_1_LOW,
79 RxUnicastFramesReceivedOK = SUNI1x10GEXP_REG_MSTAT_COUNTER_4_LOW,
80 RxMulticastFramesReceivedOK = SUNI1x10GEXP_REG_MSTAT_COUNTER_5_LOW,
81 RxBroadcastFramesReceivedOK = SUNI1x10GEXP_REG_MSTAT_COUNTER_6_LOW,
82 RxPAUSEMACCtrlFramesReceived = SUNI1x10GEXP_REG_MSTAT_COUNTER_8_LOW,
83 RxFrameCheckSequenceErrors = SUNI1x10GEXP_REG_MSTAT_COUNTER_10_LOW,
84 RxFramesLostDueToInternalMACErrors = SUNI1x10GEXP_REG_MSTAT_COUNTER_11_LOW,
85 RxSymbolErrors = SUNI1x10GEXP_REG_MSTAT_COUNTER_12_LOW,
86 RxInRangeLengthErrors = SUNI1x10GEXP_REG_MSTAT_COUNTER_13_LOW,
87 RxFramesTooLongErrors = SUNI1x10GEXP_REG_MSTAT_COUNTER_15_LOW,
88 RxJabbers = SUNI1x10GEXP_REG_MSTAT_COUNTER_16_LOW,
89 RxFragments = SUNI1x10GEXP_REG_MSTAT_COUNTER_17_LOW,
90 RxUndersizedFrames = SUNI1x10GEXP_REG_MSTAT_COUNTER_18_LOW,
91
92 TxOctetsTransmittedOK = SUNI1x10GEXP_REG_MSTAT_COUNTER_33_LOW,
93 TxFramesLostDueToInternalMACTransmissionError = SUNI1x10GEXP_REG_MSTAT_COUNTER_35_LOW,
94 TxTransmitSystemError = SUNI1x10GEXP_REG_MSTAT_COUNTER_36_LOW,
95 TxUnicastFramesTransmittedOK = SUNI1x10GEXP_REG_MSTAT_COUNTER_38_LOW,
96 TxMulticastFramesTransmittedOK = SUNI1x10GEXP_REG_MSTAT_COUNTER_40_LOW,
97 TxBroadcastFramesTransmittedOK = SUNI1x10GEXP_REG_MSTAT_COUNTER_42_LOW,
98 TxPAUSEMACCtrlFramesTransmitted = SUNI1x10GEXP_REG_MSTAT_COUNTER_43_LOW
99};
100
101struct _cmac_instance {
102 u8 enabled;
103 u8 fc;
104 u8 mac_addr[6];
105};
106
107static int pmread(struct cmac *cmac, u32 reg, u32 * data32)
108{
109 t1_tpi_read(cmac->adapter, OFFSET(reg), data32);
110 return 0;
111}
112
113static int pmwrite(struct cmac *cmac, u32 reg, u32 data32)
114{
115 t1_tpi_write(cmac->adapter, OFFSET(reg), data32);
116 return 0;
117}
118
119/* Port reset. */
120static int pm3393_reset(struct cmac *cmac)
121{
122 return 0;
123}
124
125/*
126 * Enable interrupts for the PM3393
127
128 1. Enable PM3393 BLOCK interrupts.
129 2. Enable PM3393 Master Interrupt bit(INTE)
130 3. Enable ELMER's PM3393 bit.
131 4. Enable Terminator external interrupt.
132*/
133static int pm3393_interrupt_enable(struct cmac *cmac)
134{
135 u32 pl_intr;
136
137 /* PM3393 - Enabling all hardware block interrupts.
138 */
139 pmwrite(cmac, SUNI1x10GEXP_REG_SERDES_3125_INTERRUPT_ENABLE, 0xffff);
140 pmwrite(cmac, SUNI1x10GEXP_REG_XRF_INTERRUPT_ENABLE, 0xffff);
141 pmwrite(cmac, SUNI1x10GEXP_REG_XRF_DIAG_INTERRUPT_ENABLE, 0xffff);
142 pmwrite(cmac, SUNI1x10GEXP_REG_RXOAM_INTERRUPT_ENABLE, 0xffff);
143
144 /* Don't interrupt on statistics overflow, we are polling */
145 pmwrite(cmac, SUNI1x10GEXP_REG_MSTAT_INTERRUPT_MASK_0, 0);
146 pmwrite(cmac, SUNI1x10GEXP_REG_MSTAT_INTERRUPT_MASK_1, 0);
147 pmwrite(cmac, SUNI1x10GEXP_REG_MSTAT_INTERRUPT_MASK_2, 0);
148 pmwrite(cmac, SUNI1x10GEXP_REG_MSTAT_INTERRUPT_MASK_3, 0);
149
150 pmwrite(cmac, SUNI1x10GEXP_REG_IFLX_FIFO_OVERFLOW_ENABLE, 0xffff);
151 pmwrite(cmac, SUNI1x10GEXP_REG_PL4ODP_INTERRUPT_MASK, 0xffff);
152 pmwrite(cmac, SUNI1x10GEXP_REG_XTEF_INTERRUPT_ENABLE, 0xffff);
153 pmwrite(cmac, SUNI1x10GEXP_REG_TXOAM_INTERRUPT_ENABLE, 0xffff);
154 pmwrite(cmac, SUNI1x10GEXP_REG_RXXG_CONFIG_3, 0xffff);
155 pmwrite(cmac, SUNI1x10GEXP_REG_PL4IO_LOCK_DETECT_MASK, 0xffff);
156 pmwrite(cmac, SUNI1x10GEXP_REG_TXXG_CONFIG_3, 0xffff);
157 pmwrite(cmac, SUNI1x10GEXP_REG_PL4IDU_INTERRUPT_MASK, 0xffff);
158 pmwrite(cmac, SUNI1x10GEXP_REG_EFLX_FIFO_OVERFLOW_ERROR_ENABLE, 0xffff);
159
160 /* PM3393 - Global interrupt enable
161 */
162 /* TBD XXX Disable for now until we figure out why error interrupts keep asserting. */
163 pmwrite(cmac, SUNI1x10GEXP_REG_GLOBAL_INTERRUPT_ENABLE,
164 0 /*SUNI1x10GEXP_BITMSK_TOP_INTE */ );
165
166 /* TERMINATOR - PL_INTERUPTS_EXT */
167 pl_intr = readl(cmac->adapter->regs + A_PL_ENABLE);
168 pl_intr |= F_PL_INTR_EXT;
169 writel(pl_intr, cmac->adapter->regs + A_PL_ENABLE);
170 return 0;
171}
172
173static int pm3393_interrupt_disable(struct cmac *cmac)
174{
175 u32 elmer;
176
177 /* PM3393 - Enabling HW interrupt blocks. */
178 pmwrite(cmac, SUNI1x10GEXP_REG_SERDES_3125_INTERRUPT_ENABLE, 0);
179 pmwrite(cmac, SUNI1x10GEXP_REG_XRF_INTERRUPT_ENABLE, 0);
180 pmwrite(cmac, SUNI1x10GEXP_REG_XRF_DIAG_INTERRUPT_ENABLE, 0);
181 pmwrite(cmac, SUNI1x10GEXP_REG_RXOAM_INTERRUPT_ENABLE, 0);
182 pmwrite(cmac, SUNI1x10GEXP_REG_MSTAT_INTERRUPT_MASK_0, 0);
183 pmwrite(cmac, SUNI1x10GEXP_REG_MSTAT_INTERRUPT_MASK_1, 0);
184 pmwrite(cmac, SUNI1x10GEXP_REG_MSTAT_INTERRUPT_MASK_2, 0);
185 pmwrite(cmac, SUNI1x10GEXP_REG_MSTAT_INTERRUPT_MASK_3, 0);
186 pmwrite(cmac, SUNI1x10GEXP_REG_IFLX_FIFO_OVERFLOW_ENABLE, 0);
187 pmwrite(cmac, SUNI1x10GEXP_REG_PL4ODP_INTERRUPT_MASK, 0);
188 pmwrite(cmac, SUNI1x10GEXP_REG_XTEF_INTERRUPT_ENABLE, 0);
189 pmwrite(cmac, SUNI1x10GEXP_REG_TXOAM_INTERRUPT_ENABLE, 0);
190 pmwrite(cmac, SUNI1x10GEXP_REG_RXXG_CONFIG_3, 0);
191 pmwrite(cmac, SUNI1x10GEXP_REG_PL4IO_LOCK_DETECT_MASK, 0);
192 pmwrite(cmac, SUNI1x10GEXP_REG_TXXG_CONFIG_3, 0);
193 pmwrite(cmac, SUNI1x10GEXP_REG_PL4IDU_INTERRUPT_MASK, 0);
194 pmwrite(cmac, SUNI1x10GEXP_REG_EFLX_FIFO_OVERFLOW_ERROR_ENABLE, 0);
195
196 /* PM3393 - Global interrupt enable */
197 pmwrite(cmac, SUNI1x10GEXP_REG_GLOBAL_INTERRUPT_ENABLE, 0);
198
199 /* ELMER - External chip interrupts. */
200 t1_tpi_read(cmac->adapter, A_ELMER0_INT_ENABLE, &elmer);
201 elmer &= ~ELMER0_GP_BIT1;
202 t1_tpi_write(cmac->adapter, A_ELMER0_INT_ENABLE, elmer);
203
204 /* TERMINATOR - PL_INTERUPTS_EXT */
205 /* DO NOT DISABLE TERMINATOR's EXTERNAL INTERRUPTS. ANOTHER CHIP
206 * COULD WANT THEM ENABLED. We disable PM3393 at the ELMER level.
207 */
208
209 return 0;
210}
211
212static int pm3393_interrupt_clear(struct cmac *cmac)
213{
214 u32 elmer;
215 u32 pl_intr;
216 u32 val32;
217
218 /* PM3393 - Clearing HW interrupt blocks. Note, this assumes
219 * bit WCIMODE=0 for a clear-on-read.
220 */
221 pmread(cmac, SUNI1x10GEXP_REG_SERDES_3125_INTERRUPT_STATUS, &val32);
222 pmread(cmac, SUNI1x10GEXP_REG_XRF_INTERRUPT_STATUS, &val32);
223 pmread(cmac, SUNI1x10GEXP_REG_XRF_DIAG_INTERRUPT_STATUS, &val32);
224 pmread(cmac, SUNI1x10GEXP_REG_RXOAM_INTERRUPT_STATUS, &val32);
225 pmread(cmac, SUNI1x10GEXP_REG_PL4ODP_INTERRUPT, &val32);
226 pmread(cmac, SUNI1x10GEXP_REG_XTEF_INTERRUPT_STATUS, &val32);
227 pmread(cmac, SUNI1x10GEXP_REG_IFLX_FIFO_OVERFLOW_INTERRUPT, &val32);
228 pmread(cmac, SUNI1x10GEXP_REG_TXOAM_INTERRUPT_STATUS, &val32);
229 pmread(cmac, SUNI1x10GEXP_REG_RXXG_INTERRUPT, &val32);
230 pmread(cmac, SUNI1x10GEXP_REG_TXXG_INTERRUPT, &val32);
231 pmread(cmac, SUNI1x10GEXP_REG_PL4IDU_INTERRUPT, &val32);
232 pmread(cmac, SUNI1x10GEXP_REG_EFLX_FIFO_OVERFLOW_ERROR_INDICATION,
233 &val32);
234 pmread(cmac, SUNI1x10GEXP_REG_PL4IO_LOCK_DETECT_STATUS, &val32);
235 pmread(cmac, SUNI1x10GEXP_REG_PL4IO_LOCK_DETECT_CHANGE, &val32);
236
237 /* PM3393 - Global interrupt status
238 */
239 pmread(cmac, SUNI1x10GEXP_REG_MASTER_INTERRUPT_STATUS, &val32);
240
241 /* ELMER - External chip interrupts.
242 */
243 t1_tpi_read(cmac->adapter, A_ELMER0_INT_CAUSE, &elmer);
244 elmer |= ELMER0_GP_BIT1;
245 t1_tpi_write(cmac->adapter, A_ELMER0_INT_CAUSE, elmer);
246
247 /* TERMINATOR - PL_INTERUPTS_EXT
248 */
249 pl_intr = readl(cmac->adapter->regs + A_PL_CAUSE);
250 pl_intr |= F_PL_INTR_EXT;
251 writel(pl_intr, cmac->adapter->regs + A_PL_CAUSE);
252
253 return 0;
254}
255
256/* Interrupt handler */
257static int pm3393_interrupt_handler(struct cmac *cmac)
258{
259 u32 master_intr_status;
260/*
261 1. Read master interrupt register.
262 2. Read BLOCK's interrupt status registers.
263 3. Handle BLOCK interrupts.
264*/
265 /* Read the master interrupt status register. */
266 pmread(cmac, SUNI1x10GEXP_REG_MASTER_INTERRUPT_STATUS,
267 &master_intr_status);
268
269 /* TBD XXX Lets just clear everything for now */
270 pm3393_interrupt_clear(cmac);
271
272 return 0;
273}
274
275static int pm3393_enable(struct cmac *cmac, int which)
276{
277 if (which & MAC_DIRECTION_RX)
278 pmwrite(cmac, SUNI1x10GEXP_REG_RXXG_CONFIG_1,
279 (RXXG_CONF1_VAL | SUNI1x10GEXP_BITMSK_RXXG_RXEN));
280
281 if (which & MAC_DIRECTION_TX) {
282 u32 val = TXXG_CONF1_VAL | SUNI1x10GEXP_BITMSK_TXXG_TXEN0;
283
284 if (cmac->instance->fc & PAUSE_RX)
285 val |= SUNI1x10GEXP_BITMSK_TXXG_FCRX;
286 if (cmac->instance->fc & PAUSE_TX)
287 val |= SUNI1x10GEXP_BITMSK_TXXG_FCTX;
288 pmwrite(cmac, SUNI1x10GEXP_REG_TXXG_CONFIG_1, val);
289 }
290
291 cmac->instance->enabled |= which;
292 return 0;
293}
294
295static int pm3393_enable_port(struct cmac *cmac, int which)
296{
297 /* Clear port statistics */
298 pmwrite(cmac, SUNI1x10GEXP_REG_MSTAT_CONTROL,
299 SUNI1x10GEXP_BITMSK_MSTAT_CLEAR);
300 udelay(2);
301 memset(&cmac->stats, 0, sizeof(struct cmac_statistics));
302
303 pm3393_enable(cmac, which);
304
305 /*
306 * XXX This should be done by the PHY and preferrably not at all.
307 * The PHY doesn't give us link status indication on its own so have
308 * the link management code query it instead.
309 */
310 {
311 extern void link_changed(adapter_t *adapter, int port_id);
312
313 link_changed(cmac->adapter, 0);
314 }
315 return 0;
316}
317
318static int pm3393_disable(struct cmac *cmac, int which)
319{
320 if (which & MAC_DIRECTION_RX)
321 pmwrite(cmac, SUNI1x10GEXP_REG_RXXG_CONFIG_1, RXXG_CONF1_VAL);
322 if (which & MAC_DIRECTION_TX)
323 pmwrite(cmac, SUNI1x10GEXP_REG_TXXG_CONFIG_1, TXXG_CONF1_VAL);
324
325 /*
326 * The disable is graceful. Give the PM3393 time. Can't wait very
327 * long here, we may be holding locks.
328 */
329 udelay(20);
330
331 cmac->instance->enabled &= ~which;
332 return 0;
333}
334
335static int pm3393_loopback_enable(struct cmac *cmac)
336{
337 return 0;
338}
339
340static int pm3393_loopback_disable(struct cmac *cmac)
341{
342 return 0;
343}
344
345static int pm3393_set_mtu(struct cmac *cmac, int mtu)
346{
347 int enabled = cmac->instance->enabled;
348
349 /* MAX_FRAME_SIZE includes header + FCS, mtu doesn't */
350 mtu += 14 + 4;
351 if (mtu > MAX_FRAME_SIZE)
352 return -EINVAL;
353
354 /* Disable Rx/Tx MAC before configuring it. */
355 if (enabled)
356 pm3393_disable(cmac, MAC_DIRECTION_RX | MAC_DIRECTION_TX);
357
358 pmwrite(cmac, SUNI1x10GEXP_REG_RXXG_MAX_FRAME_LENGTH, mtu);
359 pmwrite(cmac, SUNI1x10GEXP_REG_TXXG_MAX_FRAME_SIZE, mtu);
360
361 if (enabled)
362 pm3393_enable(cmac, enabled);
363 return 0;
364}
365
366static u32 calc_crc(u8 *b, int len)
367{
368 int i;
369 u32 crc = (u32)~0;
370
371 /* calculate crc one bit at a time */
372 while (len--) {
373 crc ^= *b++;
374 for (i = 0; i < 8; i++) {
375 if (crc & 0x1)
376 crc = (crc >> 1) ^ 0xedb88320;
377 else
378 crc = (crc >> 1);
379 }
380 }
381
382 /* reverse bits */
383 crc = ((crc >> 4) & 0x0f0f0f0f) | ((crc << 4) & 0xf0f0f0f0);
384 crc = ((crc >> 2) & 0x33333333) | ((crc << 2) & 0xcccccccc);
385 crc = ((crc >> 1) & 0x55555555) | ((crc << 1) & 0xaaaaaaaa);
386 /* swap bytes */
387 crc = (crc >> 16) | (crc << 16);
388 crc = (crc >> 8 & 0x00ff00ff) | (crc << 8 & 0xff00ff00);
389
390 return crc;
391}
392
393static int pm3393_set_rx_mode(struct cmac *cmac, struct t1_rx_mode *rm)
394{
395 int enabled = cmac->instance->enabled & MAC_DIRECTION_RX;
396 u32 rx_mode;
397
398 /* Disable MAC RX before reconfiguring it */
399 if (enabled)
400 pm3393_disable(cmac, MAC_DIRECTION_RX);
401
402 pmread(cmac, SUNI1x10GEXP_REG_RXXG_ADDRESS_FILTER_CONTROL_2, &rx_mode);
403 rx_mode &= ~(SUNI1x10GEXP_BITMSK_RXXG_PMODE |
404 SUNI1x10GEXP_BITMSK_RXXG_MHASH_EN);
405 pmwrite(cmac, SUNI1x10GEXP_REG_RXXG_ADDRESS_FILTER_CONTROL_2,
406 (u16)rx_mode);
407
408 if (t1_rx_mode_promisc(rm)) {
409 /* Promiscuous mode. */
410 rx_mode |= SUNI1x10GEXP_BITMSK_RXXG_PMODE;
411 }
412 if (t1_rx_mode_allmulti(rm)) {
413 /* Accept all multicast. */
414 pmwrite(cmac, SUNI1x10GEXP_REG_RXXG_MULTICAST_HASH_LOW, 0xffff);
415 pmwrite(cmac, SUNI1x10GEXP_REG_RXXG_MULTICAST_HASH_MIDLOW, 0xffff);
416 pmwrite(cmac, SUNI1x10GEXP_REG_RXXG_MULTICAST_HASH_MIDHIGH, 0xffff);
417 pmwrite(cmac, SUNI1x10GEXP_REG_RXXG_MULTICAST_HASH_HIGH, 0xffff);
418 rx_mode |= SUNI1x10GEXP_BITMSK_RXXG_MHASH_EN;
419 } else if (t1_rx_mode_mc_cnt(rm)) {
420 /* Accept one or more multicast(s). */
421 u8 *addr;
422 int bit;
423 u16 mc_filter[4] = { 0, };
424
425 while ((addr = t1_get_next_mcaddr(rm))) {
426 bit = (calc_crc(addr, ETH_ALEN) >> 23) & 0x3f; /* bit[23:28] */
427 mc_filter[bit >> 4] |= 1 << (bit & 0xf);
428 }
429 pmwrite(cmac, SUNI1x10GEXP_REG_RXXG_MULTICAST_HASH_LOW, mc_filter[0]);
430 pmwrite(cmac, SUNI1x10GEXP_REG_RXXG_MULTICAST_HASH_MIDLOW, mc_filter[1]);
431 pmwrite(cmac, SUNI1x10GEXP_REG_RXXG_MULTICAST_HASH_MIDHIGH, mc_filter[2]);
432 pmwrite(cmac, SUNI1x10GEXP_REG_RXXG_MULTICAST_HASH_HIGH, mc_filter[3]);
433 rx_mode |= SUNI1x10GEXP_BITMSK_RXXG_MHASH_EN;
434 }
435
436 pmwrite(cmac, SUNI1x10GEXP_REG_RXXG_ADDRESS_FILTER_CONTROL_2, (u16)rx_mode);
437
438 if (enabled)
439 pm3393_enable(cmac, MAC_DIRECTION_RX);
440
441 return 0;
442}
443
444static int pm3393_get_speed_duplex_fc(struct cmac *cmac, int *speed,
445 int *duplex, int *fc)
446{
447 if (speed)
448 *speed = SPEED_10000;
449 if (duplex)
450 *duplex = DUPLEX_FULL;
451 if (fc)
452 *fc = cmac->instance->fc;
453 return 0;
454}
455
456static int pm3393_set_speed_duplex_fc(struct cmac *cmac, int speed, int duplex,
457 int fc)
458{
459 if (speed >= 0 && speed != SPEED_10000)
460 return -1;
461 if (duplex >= 0 && duplex != DUPLEX_FULL)
462 return -1;
463 if (fc & ~(PAUSE_TX | PAUSE_RX))
464 return -1;
465
466 if (fc != cmac->instance->fc) {
467 cmac->instance->fc = (u8) fc;
468 if (cmac->instance->enabled & MAC_DIRECTION_TX)
469 pm3393_enable(cmac, MAC_DIRECTION_TX);
470 }
471 return 0;
472}
473
474#define RMON_UPDATE(mac, name, stat_name) \
475 { \
476 t1_tpi_read((mac)->adapter, OFFSET(name), &val0); \
477 t1_tpi_read((mac)->adapter, OFFSET(((name)+1)), &val1); \
478 t1_tpi_read((mac)->adapter, OFFSET(((name)+2)), &val2); \
479 (mac)->stats.stat_name = ((u64)val0 & 0xffff) | \
480 (((u64)val1 & 0xffff) << 16) | \
481 (((u64)val2 & 0xff) << 32) | \
482 ((mac)->stats.stat_name & \
483 (~(u64)0 << 40)); \
484 if (ro & \
485 ((name - SUNI1x10GEXP_REG_MSTAT_COUNTER_0_LOW) >> 2)) \
486 (mac)->stats.stat_name += ((u64)1 << 40); \
487 }
488
489static const struct cmac_statistics *pm3393_update_statistics(struct cmac *mac,
490 int flag)
491{
492 u64 ro;
493 u32 val0, val1, val2, val3;
494
495 /* Snap the counters */
496 pmwrite(mac, SUNI1x10GEXP_REG_MSTAT_CONTROL,
497 SUNI1x10GEXP_BITMSK_MSTAT_SNAP);
498
499 /* Counter rollover, clear on read */
500 pmread(mac, SUNI1x10GEXP_REG_MSTAT_COUNTER_ROLLOVER_0, &val0);
501 pmread(mac, SUNI1x10GEXP_REG_MSTAT_COUNTER_ROLLOVER_1, &val1);
502 pmread(mac, SUNI1x10GEXP_REG_MSTAT_COUNTER_ROLLOVER_2, &val2);
503 pmread(mac, SUNI1x10GEXP_REG_MSTAT_COUNTER_ROLLOVER_3, &val3);
504 ro = ((u64)val0 & 0xffff) | (((u64)val1 & 0xffff) << 16) |
505 (((u64)val2 & 0xffff) << 32) | (((u64)val3 & 0xffff) << 48);
506
507 /* Rx stats */
508 RMON_UPDATE(mac, RxOctetsReceivedOK, RxOctetsOK);
509 RMON_UPDATE(mac, RxUnicastFramesReceivedOK, RxUnicastFramesOK);
510 RMON_UPDATE(mac, RxMulticastFramesReceivedOK, RxMulticastFramesOK);
511 RMON_UPDATE(mac, RxBroadcastFramesReceivedOK, RxBroadcastFramesOK);
512 RMON_UPDATE(mac, RxPAUSEMACCtrlFramesReceived, RxPauseFrames);
513 RMON_UPDATE(mac, RxFrameCheckSequenceErrors, RxFCSErrors);
514 RMON_UPDATE(mac, RxFramesLostDueToInternalMACErrors,
515 RxInternalMACRcvError);
516 RMON_UPDATE(mac, RxSymbolErrors, RxSymbolErrors);
517 RMON_UPDATE(mac, RxInRangeLengthErrors, RxInRangeLengthErrors);
518 RMON_UPDATE(mac, RxFramesTooLongErrors , RxFrameTooLongErrors);
519 RMON_UPDATE(mac, RxJabbers, RxJabberErrors);
520 RMON_UPDATE(mac, RxFragments, RxRuntErrors);
521 RMON_UPDATE(mac, RxUndersizedFrames, RxRuntErrors);
522
523 /* Tx stats */
524 RMON_UPDATE(mac, TxOctetsTransmittedOK, TxOctetsOK);
525 RMON_UPDATE(mac, TxFramesLostDueToInternalMACTransmissionError,
526 TxInternalMACXmitError);
527 RMON_UPDATE(mac, TxTransmitSystemError, TxFCSErrors);
528 RMON_UPDATE(mac, TxUnicastFramesTransmittedOK, TxUnicastFramesOK);
529 RMON_UPDATE(mac, TxMulticastFramesTransmittedOK, TxMulticastFramesOK);
530 RMON_UPDATE(mac, TxBroadcastFramesTransmittedOK, TxBroadcastFramesOK);
531 RMON_UPDATE(mac, TxPAUSEMACCtrlFramesTransmitted, TxPauseFrames);
532
533 return &mac->stats;
534}
535
536static int pm3393_macaddress_get(struct cmac *cmac, u8 mac_addr[6])
537{
538 memcpy(mac_addr, cmac->instance->mac_addr, 6);
539 return 0;
540}
541
542static int pm3393_macaddress_set(struct cmac *cmac, u8 ma[6])
543{
544 u32 val, lo, mid, hi, enabled = cmac->instance->enabled;
545
546 /*
547 * MAC addr: 00:07:43:00:13:09
548 *
549 * ma[5] = 0x09
550 * ma[4] = 0x13
551 * ma[3] = 0x00
552 * ma[2] = 0x43
553 * ma[1] = 0x07
554 * ma[0] = 0x00
555 *
556 * The PM3393 requires byte swapping and reverse order entry
557 * when programming MAC addresses:
558 *
559 * low_bits[15:0] = ma[1]:ma[0]
560 * mid_bits[31:16] = ma[3]:ma[2]
561 * high_bits[47:32] = ma[5]:ma[4]
562 */
563
564 /* Store local copy */
565 memcpy(cmac->instance->mac_addr, ma, 6);
566
567 lo = ((u32) ma[1] << 8) | (u32) ma[0];
568 mid = ((u32) ma[3] << 8) | (u32) ma[2];
569 hi = ((u32) ma[5] << 8) | (u32) ma[4];
570
571 /* Disable Rx/Tx MAC before configuring it. */
572 if (enabled)
573 pm3393_disable(cmac, MAC_DIRECTION_RX | MAC_DIRECTION_TX);
574
575 /* Set RXXG Station Address */
576 pmwrite(cmac, SUNI1x10GEXP_REG_RXXG_SA_15_0, lo);
577 pmwrite(cmac, SUNI1x10GEXP_REG_RXXG_SA_31_16, mid);
578 pmwrite(cmac, SUNI1x10GEXP_REG_RXXG_SA_47_32, hi);
579
580 /* Set TXXG Station Address */
581 pmwrite(cmac, SUNI1x10GEXP_REG_TXXG_SA_15_0, lo);
582 pmwrite(cmac, SUNI1x10GEXP_REG_TXXG_SA_31_16, mid);
583 pmwrite(cmac, SUNI1x10GEXP_REG_TXXG_SA_47_32, hi);
584
585 /* Setup Exact Match Filter 1 with our MAC address
586 *
587 * Must disable exact match filter before configuring it.
588 */
589 pmread(cmac, SUNI1x10GEXP_REG_RXXG_ADDRESS_FILTER_CONTROL_0, &val);
590 val &= 0xff0f;
591 pmwrite(cmac, SUNI1x10GEXP_REG_RXXG_ADDRESS_FILTER_CONTROL_0, val);
592
593 pmwrite(cmac, SUNI1x10GEXP_REG_RXXG_EXACT_MATCH_ADDR_1_LOW, lo);
594 pmwrite(cmac, SUNI1x10GEXP_REG_RXXG_EXACT_MATCH_ADDR_1_MID, mid);
595 pmwrite(cmac, SUNI1x10GEXP_REG_RXXG_EXACT_MATCH_ADDR_1_HIGH, hi);
596
597 val |= 0x0090;
598 pmwrite(cmac, SUNI1x10GEXP_REG_RXXG_ADDRESS_FILTER_CONTROL_0, val);
599
600 if (enabled)
601 pm3393_enable(cmac, enabled);
602 return 0;
603}
604
605static void pm3393_destroy(struct cmac *cmac)
606{
607 kfree(cmac);
608}
609
610static struct cmac_ops pm3393_ops = {
611 .destroy = pm3393_destroy,
612 .reset = pm3393_reset,
613 .interrupt_enable = pm3393_interrupt_enable,
614 .interrupt_disable = pm3393_interrupt_disable,
615 .interrupt_clear = pm3393_interrupt_clear,
616 .interrupt_handler = pm3393_interrupt_handler,
617 .enable = pm3393_enable_port,
618 .disable = pm3393_disable,
619 .loopback_enable = pm3393_loopback_enable,
620 .loopback_disable = pm3393_loopback_disable,
621 .set_mtu = pm3393_set_mtu,
622 .set_rx_mode = pm3393_set_rx_mode,
623 .get_speed_duplex_fc = pm3393_get_speed_duplex_fc,
624 .set_speed_duplex_fc = pm3393_set_speed_duplex_fc,
625 .statistics_update = pm3393_update_statistics,
626 .macaddress_get = pm3393_macaddress_get,
627 .macaddress_set = pm3393_macaddress_set
628};
629
630static struct cmac *pm3393_mac_create(adapter_t *adapter, int index)
631{
632 struct cmac *cmac;
633
634 cmac = kmalloc(sizeof(*cmac) + sizeof(cmac_instance), GFP_KERNEL);
635 if (!cmac)
636 return NULL;
637 memset(cmac, 0, sizeof(*cmac));
638
639 cmac->ops = &pm3393_ops;
640 cmac->instance = (cmac_instance *) (cmac + 1);
641 cmac->adapter = adapter;
642 cmac->instance->fc = PAUSE_TX | PAUSE_RX;
643
644 t1_tpi_write(adapter, OFFSET(0x0001), 0x00008000);
645 t1_tpi_write(adapter, OFFSET(0x0001), 0x00000000);
646 t1_tpi_write(adapter, OFFSET(0x2308), 0x00009800);
647 t1_tpi_write(adapter, OFFSET(0x2305), 0x00001001); /* PL4IO Enable */
648 t1_tpi_write(adapter, OFFSET(0x2320), 0x00008800);
649 t1_tpi_write(adapter, OFFSET(0x2321), 0x00008800);
650 t1_tpi_write(adapter, OFFSET(0x2322), 0x00008800);
651 t1_tpi_write(adapter, OFFSET(0x2323), 0x00008800);
652 t1_tpi_write(adapter, OFFSET(0x2324), 0x00008800);
653 t1_tpi_write(adapter, OFFSET(0x2325), 0x00008800);
654 t1_tpi_write(adapter, OFFSET(0x2326), 0x00008800);
655 t1_tpi_write(adapter, OFFSET(0x2327), 0x00008800);
656 t1_tpi_write(adapter, OFFSET(0x2328), 0x00008800);
657 t1_tpi_write(adapter, OFFSET(0x2329), 0x00008800);
658 t1_tpi_write(adapter, OFFSET(0x232a), 0x00008800);
659 t1_tpi_write(adapter, OFFSET(0x232b), 0x00008800);
660 t1_tpi_write(adapter, OFFSET(0x232c), 0x00008800);
661 t1_tpi_write(adapter, OFFSET(0x232d), 0x00008800);
662 t1_tpi_write(adapter, OFFSET(0x232e), 0x00008800);
663 t1_tpi_write(adapter, OFFSET(0x232f), 0x00008800);
664 t1_tpi_write(adapter, OFFSET(0x230d), 0x00009c00);
665 t1_tpi_write(adapter, OFFSET(0x2304), 0x00000202); /* PL4IO Calendar Repetitions */
666
667 t1_tpi_write(adapter, OFFSET(0x3200), 0x00008080); /* EFLX Enable */
668 t1_tpi_write(adapter, OFFSET(0x3210), 0x00000000); /* EFLX Channel Deprovision */
669 t1_tpi_write(adapter, OFFSET(0x3203), 0x00000000); /* EFLX Low Limit */
670 t1_tpi_write(adapter, OFFSET(0x3204), 0x00000040); /* EFLX High Limit */
671 t1_tpi_write(adapter, OFFSET(0x3205), 0x000002cc); /* EFLX Almost Full */
672 t1_tpi_write(adapter, OFFSET(0x3206), 0x00000199); /* EFLX Almost Empty */
673 t1_tpi_write(adapter, OFFSET(0x3207), 0x00000240); /* EFLX Cut Through Threshold */
674 t1_tpi_write(adapter, OFFSET(0x3202), 0x00000000); /* EFLX Indirect Register Update */
675 t1_tpi_write(adapter, OFFSET(0x3210), 0x00000001); /* EFLX Channel Provision */
676 t1_tpi_write(adapter, OFFSET(0x3208), 0x0000ffff); /* EFLX Undocumented */
677 t1_tpi_write(adapter, OFFSET(0x320a), 0x0000ffff); /* EFLX Undocumented */
678 t1_tpi_write(adapter, OFFSET(0x320c), 0x0000ffff); /* EFLX enable overflow interrupt The other bit are undocumented */
679 t1_tpi_write(adapter, OFFSET(0x320e), 0x0000ffff); /* EFLX Undocumented */
680
681 t1_tpi_write(adapter, OFFSET(0x2200), 0x0000c000); /* IFLX Configuration - enable */
682 t1_tpi_write(adapter, OFFSET(0x2201), 0x00000000); /* IFLX Channel Deprovision */
683 t1_tpi_write(adapter, OFFSET(0x220e), 0x00000000); /* IFLX Low Limit */
684 t1_tpi_write(adapter, OFFSET(0x220f), 0x00000100); /* IFLX High Limit */
685 t1_tpi_write(adapter, OFFSET(0x2210), 0x00000c00); /* IFLX Almost Full Limit */
686 t1_tpi_write(adapter, OFFSET(0x2211), 0x00000599); /* IFLX Almost Empty Limit */
687 t1_tpi_write(adapter, OFFSET(0x220d), 0x00000000); /* IFLX Indirect Register Update */
688 t1_tpi_write(adapter, OFFSET(0x2201), 0x00000001); /* IFLX Channel Provision */
689 t1_tpi_write(adapter, OFFSET(0x2203), 0x0000ffff); /* IFLX Undocumented */
690 t1_tpi_write(adapter, OFFSET(0x2205), 0x0000ffff); /* IFLX Undocumented */
691 t1_tpi_write(adapter, OFFSET(0x2209), 0x0000ffff); /* IFLX Enable overflow interrupt. The other bit are undocumented */
692
693 t1_tpi_write(adapter, OFFSET(0x2241), 0xfffffffe); /* PL4MOS Undocumented */
694 t1_tpi_write(adapter, OFFSET(0x2242), 0x0000ffff); /* PL4MOS Undocumented */
695 t1_tpi_write(adapter, OFFSET(0x2243), 0x00000008); /* PL4MOS Starving Burst Size */
696 t1_tpi_write(adapter, OFFSET(0x2244), 0x00000008); /* PL4MOS Hungry Burst Size */
697 t1_tpi_write(adapter, OFFSET(0x2245), 0x00000008); /* PL4MOS Transfer Size */
698 t1_tpi_write(adapter, OFFSET(0x2240), 0x00000005); /* PL4MOS Disable */
699
700 t1_tpi_write(adapter, OFFSET(0x2280), 0x00002103); /* PL4ODP Training Repeat and SOP rule */
701 t1_tpi_write(adapter, OFFSET(0x2284), 0x00000000); /* PL4ODP MAX_T setting */
702
703 t1_tpi_write(adapter, OFFSET(0x3280), 0x00000087); /* PL4IDU Enable data forward, port state machine. Set ALLOW_NON_ZERO_OLB */
704 t1_tpi_write(adapter, OFFSET(0x3282), 0x0000001f); /* PL4IDU Enable Dip4 check error interrupts */
705
706 t1_tpi_write(adapter, OFFSET(0x3040), 0x0c32); /* # TXXG Config */
707 /* For T1 use timer based Mac flow control. */
708 t1_tpi_write(adapter, OFFSET(0x304d), 0x8000);
709 t1_tpi_write(adapter, OFFSET(0x2040), 0x059c); /* # RXXG Config */
710 t1_tpi_write(adapter, OFFSET(0x2049), 0x0001); /* # RXXG Cut Through */
711 t1_tpi_write(adapter, OFFSET(0x2070), 0x0000); /* # Disable promiscuous mode */
712
713 /* Setup Exact Match Filter 0 to allow broadcast packets.
714 */
715 t1_tpi_write(adapter, OFFSET(0x206e), 0x0000); /* # Disable Match Enable bit */
716 t1_tpi_write(adapter, OFFSET(0x204a), 0xffff); /* # low addr */
717 t1_tpi_write(adapter, OFFSET(0x204b), 0xffff); /* # mid addr */
718 t1_tpi_write(adapter, OFFSET(0x204c), 0xffff); /* # high addr */
719 t1_tpi_write(adapter, OFFSET(0x206e), 0x0009); /* # Enable Match Enable bit */
720
721 t1_tpi_write(adapter, OFFSET(0x0003), 0x0000); /* # NO SOP/ PAD_EN setup */
722 t1_tpi_write(adapter, OFFSET(0x0100), 0x0ff0); /* # RXEQB disabled */
723 t1_tpi_write(adapter, OFFSET(0x0101), 0x0f0f); /* # No Preemphasis */
724
725 return cmac;
726}
727
728static int pm3393_mac_reset(adapter_t * adapter)
729{
730 u32 val;
731 u32 x;
732 u32 is_pl4_reset_finished;
733 u32 is_pl4_outof_lock;
734 u32 is_xaui_mabc_pll_locked;
735 u32 successful_reset;
736 int i;
737
738 /* The following steps are required to properly reset
739 * the PM3393. This information is provided in the
740 * PM3393 datasheet (Issue 2: November 2002)
741 * section 13.1 -- Device Reset.
742 *
743 * The PM3393 has three types of components that are
744 * individually reset:
745 *
746 * DRESETB - Digital circuitry
747 * PL4_ARESETB - PL4 analog circuitry
748 * XAUI_ARESETB - XAUI bus analog circuitry
749 *
750 * Steps to reset PM3393 using RSTB pin:
751 *
752 * 1. Assert RSTB pin low ( write 0 )
753 * 2. Wait at least 1ms to initiate a complete initialization of device.
754 * 3. Wait until all external clocks and REFSEL are stable.
755 * 4. Wait minimum of 1ms. (after external clocks and REFEL are stable)
756 * 5. De-assert RSTB ( write 1 )
757 * 6. Wait until internal timers to expires after ~14ms.
758 * - Allows analog clock synthesizer(PL4CSU) to stabilize to
759 * selected reference frequency before allowing the digital
760 * portion of the device to operate.
761 * 7. Wait at least 200us for XAUI interface to stabilize.
762 * 8. Verify the PM3393 came out of reset successfully.
763 * Set successful reset flag if everything worked else try again
764 * a few more times.
765 */
766
767 successful_reset = 0;
768 for (i = 0; i < 3 && !successful_reset; i++) {
769 /* 1 */
770 t1_tpi_read(adapter, A_ELMER0_GPO, &val);
771 val &= ~1;
772 t1_tpi_write(adapter, A_ELMER0_GPO, val);
773
774 /* 2 */
775 msleep(1);
776
777 /* 3 */
778 msleep(1);
779
780 /* 4 */
781 msleep(2 /*1 extra ms for safety */ );
782
783 /* 5 */
784 val |= 1;
785 t1_tpi_write(adapter, A_ELMER0_GPO, val);
786
787 /* 6 */
788 msleep(15 /*1 extra ms for safety */ );
789
790 /* 7 */
791 msleep(1);
792
793 /* 8 */
794
795 /* Has PL4 analog block come out of reset correctly? */
796 t1_tpi_read(adapter, OFFSET(SUNI1x10GEXP_REG_DEVICE_STATUS), &val);
797 is_pl4_reset_finished = (val & SUNI1x10GEXP_BITMSK_TOP_EXPIRED);
798
799 /* TBD XXX SUNI1x10GEXP_BITMSK_TOP_PL4_IS_DOOL gets locked later in the init sequence
800 * figure out why? */
801
802 /* Have all PL4 block clocks locked? */
803 x = (SUNI1x10GEXP_BITMSK_TOP_PL4_ID_DOOL
804 /*| SUNI1x10GEXP_BITMSK_TOP_PL4_IS_DOOL */ |
805 SUNI1x10GEXP_BITMSK_TOP_PL4_ID_ROOL |
806 SUNI1x10GEXP_BITMSK_TOP_PL4_IS_ROOL |
807 SUNI1x10GEXP_BITMSK_TOP_PL4_OUT_ROOL);
808 is_pl4_outof_lock = (val & x);
809
810 /* ??? If this fails, might be able to software reset the XAUI part
811 * and try to recover... thus saving us from doing another HW reset */
812 /* Has the XAUI MABC PLL circuitry stablized? */
813 is_xaui_mabc_pll_locked =
814 (val & SUNI1x10GEXP_BITMSK_TOP_SXRA_EXPIRED);
815
816 successful_reset = (is_pl4_reset_finished && !is_pl4_outof_lock
817 && is_xaui_mabc_pll_locked);
818 }
819 return successful_reset ? 0 : 1;
820}
821
822struct gmac t1_pm3393_ops = {
823 STATS_TICK_SECS,
824 pm3393_mac_create,
825 pm3393_mac_reset
826};
diff --git a/drivers/net/chelsio/regs.h b/drivers/net/chelsio/regs.h
new file mode 100644
index 000000000000..b90e11f40d1f
--- /dev/null
+++ b/drivers/net/chelsio/regs.h
@@ -0,0 +1,468 @@
1/*****************************************************************************
2 * *
3 * File: regs.h *
4 * $Revision: 1.8 $ *
5 * $Date: 2005/06/21 18:29:48 $ *
6 * Description: *
7 * part of the Chelsio 10Gb Ethernet Driver. *
8 * *
9 * This program is free software; you can redistribute it and/or modify *
10 * it under the terms of the GNU General Public License, version 2, as *
11 * published by the Free Software Foundation. *
12 * *
13 * You should have received a copy of the GNU General Public License along *
14 * with this program; if not, write to the Free Software Foundation, Inc., *
15 * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
16 * *
17 * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED *
18 * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF *
19 * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. *
20 * *
21 * http://www.chelsio.com *
22 * *
23 * Copyright (c) 2003 - 2005 Chelsio Communications, Inc. *
24 * All rights reserved. *
25 * *
26 * Maintainers: maintainers@chelsio.com *
27 * *
28 * Authors: Dimitrios Michailidis <dm@chelsio.com> *
29 * Tina Yang <tainay@chelsio.com> *
30 * Felix Marti <felix@chelsio.com> *
31 * Scott Bardone <sbardone@chelsio.com> *
32 * Kurt Ottaway <kottaway@chelsio.com> *
33 * Frank DiMambro <frank@chelsio.com> *
34 * *
35 * History: *
36 * *
37 ****************************************************************************/
38
39#ifndef _CXGB_REGS_H_
40#define _CXGB_REGS_H_
41
42/* SGE registers */
43#define A_SG_CONTROL 0x0
44
45#define S_CMDQ0_ENABLE 0
46#define V_CMDQ0_ENABLE(x) ((x) << S_CMDQ0_ENABLE)
47#define F_CMDQ0_ENABLE V_CMDQ0_ENABLE(1U)
48
49#define S_CMDQ1_ENABLE 1
50#define V_CMDQ1_ENABLE(x) ((x) << S_CMDQ1_ENABLE)
51#define F_CMDQ1_ENABLE V_CMDQ1_ENABLE(1U)
52
53#define S_FL0_ENABLE 2
54#define V_FL0_ENABLE(x) ((x) << S_FL0_ENABLE)
55#define F_FL0_ENABLE V_FL0_ENABLE(1U)
56
57#define S_FL1_ENABLE 3
58#define V_FL1_ENABLE(x) ((x) << S_FL1_ENABLE)
59#define F_FL1_ENABLE V_FL1_ENABLE(1U)
60
61#define S_CPL_ENABLE 4
62#define V_CPL_ENABLE(x) ((x) << S_CPL_ENABLE)
63#define F_CPL_ENABLE V_CPL_ENABLE(1U)
64
65#define S_RESPONSE_QUEUE_ENABLE 5
66#define V_RESPONSE_QUEUE_ENABLE(x) ((x) << S_RESPONSE_QUEUE_ENABLE)
67#define F_RESPONSE_QUEUE_ENABLE V_RESPONSE_QUEUE_ENABLE(1U)
68
69#define S_CMDQ_PRIORITY 6
70#define M_CMDQ_PRIORITY 0x3
71#define V_CMDQ_PRIORITY(x) ((x) << S_CMDQ_PRIORITY)
72#define G_CMDQ_PRIORITY(x) (((x) >> S_CMDQ_PRIORITY) & M_CMDQ_PRIORITY)
73
74#define S_DISABLE_CMDQ1_GTS 9
75#define V_DISABLE_CMDQ1_GTS(x) ((x) << S_DISABLE_CMDQ1_GTS)
76#define F_DISABLE_CMDQ1_GTS V_DISABLE_CMDQ1_GTS(1U)
77
78#define S_DISABLE_FL0_GTS 10
79#define V_DISABLE_FL0_GTS(x) ((x) << S_DISABLE_FL0_GTS)
80#define F_DISABLE_FL0_GTS V_DISABLE_FL0_GTS(1U)
81
82#define S_DISABLE_FL1_GTS 11
83#define V_DISABLE_FL1_GTS(x) ((x) << S_DISABLE_FL1_GTS)
84#define F_DISABLE_FL1_GTS V_DISABLE_FL1_GTS(1U)
85
86#define S_ENABLE_BIG_ENDIAN 12
87#define V_ENABLE_BIG_ENDIAN(x) ((x) << S_ENABLE_BIG_ENDIAN)
88#define F_ENABLE_BIG_ENDIAN V_ENABLE_BIG_ENDIAN(1U)
89
90#define S_ISCSI_COALESCE 14
91#define V_ISCSI_COALESCE(x) ((x) << S_ISCSI_COALESCE)
92#define F_ISCSI_COALESCE V_ISCSI_COALESCE(1U)
93
94#define S_RX_PKT_OFFSET 15
95#define V_RX_PKT_OFFSET(x) ((x) << S_RX_PKT_OFFSET)
96
97#define S_VLAN_XTRACT 18
98#define V_VLAN_XTRACT(x) ((x) << S_VLAN_XTRACT)
99#define F_VLAN_XTRACT V_VLAN_XTRACT(1U)
100
101#define A_SG_DOORBELL 0x4
102#define A_SG_CMD0BASELWR 0x8
103#define A_SG_CMD0BASEUPR 0xc
104#define A_SG_CMD1BASELWR 0x10
105#define A_SG_CMD1BASEUPR 0x14
106#define A_SG_FL0BASELWR 0x18
107#define A_SG_FL0BASEUPR 0x1c
108#define A_SG_FL1BASELWR 0x20
109#define A_SG_FL1BASEUPR 0x24
110#define A_SG_CMD0SIZE 0x28
111#define A_SG_FL0SIZE 0x2c
112#define A_SG_RSPSIZE 0x30
113#define A_SG_RSPBASELWR 0x34
114#define A_SG_RSPBASEUPR 0x38
115#define A_SG_FLTHRESHOLD 0x3c
116#define A_SG_RSPQUEUECREDIT 0x40
117#define A_SG_SLEEPING 0x48
118#define A_SG_INTRTIMER 0x4c
119#define A_SG_CMD1SIZE 0xb0
120#define A_SG_FL1SIZE 0xb4
121#define A_SG_INT_ENABLE 0xb8
122
123#define S_RESPQ_EXHAUSTED 0
124#define V_RESPQ_EXHAUSTED(x) ((x) << S_RESPQ_EXHAUSTED)
125#define F_RESPQ_EXHAUSTED V_RESPQ_EXHAUSTED(1U)
126
127#define S_RESPQ_OVERFLOW 1
128#define V_RESPQ_OVERFLOW(x) ((x) << S_RESPQ_OVERFLOW)
129#define F_RESPQ_OVERFLOW V_RESPQ_OVERFLOW(1U)
130
131#define S_FL_EXHAUSTED 2
132#define V_FL_EXHAUSTED(x) ((x) << S_FL_EXHAUSTED)
133#define F_FL_EXHAUSTED V_FL_EXHAUSTED(1U)
134
135#define S_PACKET_TOO_BIG 3
136#define V_PACKET_TOO_BIG(x) ((x) << S_PACKET_TOO_BIG)
137#define F_PACKET_TOO_BIG V_PACKET_TOO_BIG(1U)
138
139#define S_PACKET_MISMATCH 4
140#define V_PACKET_MISMATCH(x) ((x) << S_PACKET_MISMATCH)
141#define F_PACKET_MISMATCH V_PACKET_MISMATCH(1U)
142
143#define A_SG_INT_CAUSE 0xbc
144#define A_SG_RESPACCUTIMER 0xc0
145
146/* MC3 registers */
147
148#define S_READY 1
149#define V_READY(x) ((x) << S_READY)
150#define F_READY V_READY(1U)
151
152/* MC4 registers */
153
154#define A_MC4_CFG 0x180
155#define S_MC4_SLOW 25
156#define V_MC4_SLOW(x) ((x) << S_MC4_SLOW)
157#define F_MC4_SLOW V_MC4_SLOW(1U)
158
159/* TPI registers */
160
161#define A_TPI_ADDR 0x280
162#define A_TPI_WR_DATA 0x284
163#define A_TPI_RD_DATA 0x288
164#define A_TPI_CSR 0x28c
165
166#define S_TPIWR 0
167#define V_TPIWR(x) ((x) << S_TPIWR)
168#define F_TPIWR V_TPIWR(1U)
169
170#define S_TPIRDY 1
171#define V_TPIRDY(x) ((x) << S_TPIRDY)
172#define F_TPIRDY V_TPIRDY(1U)
173
174#define A_TPI_PAR 0x29c
175
176#define S_TPIPAR 0
177#define M_TPIPAR 0x7f
178#define V_TPIPAR(x) ((x) << S_TPIPAR)
179#define G_TPIPAR(x) (((x) >> S_TPIPAR) & M_TPIPAR)
180
181/* TP registers */
182
183#define A_TP_IN_CONFIG 0x300
184
185#define S_TP_IN_CSPI_CPL 3
186#define V_TP_IN_CSPI_CPL(x) ((x) << S_TP_IN_CSPI_CPL)
187#define F_TP_IN_CSPI_CPL V_TP_IN_CSPI_CPL(1U)
188
189#define S_TP_IN_CSPI_CHECK_IP_CSUM 5
190#define V_TP_IN_CSPI_CHECK_IP_CSUM(x) ((x) << S_TP_IN_CSPI_CHECK_IP_CSUM)
191#define F_TP_IN_CSPI_CHECK_IP_CSUM V_TP_IN_CSPI_CHECK_IP_CSUM(1U)
192
193#define S_TP_IN_CSPI_CHECK_TCP_CSUM 6
194#define V_TP_IN_CSPI_CHECK_TCP_CSUM(x) ((x) << S_TP_IN_CSPI_CHECK_TCP_CSUM)
195#define F_TP_IN_CSPI_CHECK_TCP_CSUM V_TP_IN_CSPI_CHECK_TCP_CSUM(1U)
196
197#define S_TP_IN_ESPI_ETHERNET 8
198#define V_TP_IN_ESPI_ETHERNET(x) ((x) << S_TP_IN_ESPI_ETHERNET)
199#define F_TP_IN_ESPI_ETHERNET V_TP_IN_ESPI_ETHERNET(1U)
200
201#define S_TP_IN_ESPI_CHECK_IP_CSUM 12
202#define V_TP_IN_ESPI_CHECK_IP_CSUM(x) ((x) << S_TP_IN_ESPI_CHECK_IP_CSUM)
203#define F_TP_IN_ESPI_CHECK_IP_CSUM V_TP_IN_ESPI_CHECK_IP_CSUM(1U)
204
205#define S_TP_IN_ESPI_CHECK_TCP_CSUM 13
206#define V_TP_IN_ESPI_CHECK_TCP_CSUM(x) ((x) << S_TP_IN_ESPI_CHECK_TCP_CSUM)
207#define F_TP_IN_ESPI_CHECK_TCP_CSUM V_TP_IN_ESPI_CHECK_TCP_CSUM(1U)
208
209#define S_OFFLOAD_DISABLE 14
210#define V_OFFLOAD_DISABLE(x) ((x) << S_OFFLOAD_DISABLE)
211#define F_OFFLOAD_DISABLE V_OFFLOAD_DISABLE(1U)
212
213#define A_TP_OUT_CONFIG 0x304
214
215#define S_TP_OUT_CSPI_CPL 2
216#define V_TP_OUT_CSPI_CPL(x) ((x) << S_TP_OUT_CSPI_CPL)
217#define F_TP_OUT_CSPI_CPL V_TP_OUT_CSPI_CPL(1U)
218
219#define S_TP_OUT_ESPI_ETHERNET 6
220#define V_TP_OUT_ESPI_ETHERNET(x) ((x) << S_TP_OUT_ESPI_ETHERNET)
221#define F_TP_OUT_ESPI_ETHERNET V_TP_OUT_ESPI_ETHERNET(1U)
222
223#define S_TP_OUT_ESPI_GENERATE_IP_CSUM 10
224#define V_TP_OUT_ESPI_GENERATE_IP_CSUM(x) ((x) << S_TP_OUT_ESPI_GENERATE_IP_CSUM)
225#define F_TP_OUT_ESPI_GENERATE_IP_CSUM V_TP_OUT_ESPI_GENERATE_IP_CSUM(1U)
226
227#define S_TP_OUT_ESPI_GENERATE_TCP_CSUM 11
228#define V_TP_OUT_ESPI_GENERATE_TCP_CSUM(x) ((x) << S_TP_OUT_ESPI_GENERATE_TCP_CSUM)
229#define F_TP_OUT_ESPI_GENERATE_TCP_CSUM V_TP_OUT_ESPI_GENERATE_TCP_CSUM(1U)
230
231#define A_TP_GLOBAL_CONFIG 0x308
232
233#define S_IP_TTL 0
234#define M_IP_TTL 0xff
235#define V_IP_TTL(x) ((x) << S_IP_TTL)
236
237#define S_TCP_CSUM 11
238#define V_TCP_CSUM(x) ((x) << S_TCP_CSUM)
239#define F_TCP_CSUM V_TCP_CSUM(1U)
240
241#define S_UDP_CSUM 12
242#define V_UDP_CSUM(x) ((x) << S_UDP_CSUM)
243#define F_UDP_CSUM V_UDP_CSUM(1U)
244
245#define S_IP_CSUM 13
246#define V_IP_CSUM(x) ((x) << S_IP_CSUM)
247#define F_IP_CSUM V_IP_CSUM(1U)
248
249#define S_PATH_MTU 15
250#define V_PATH_MTU(x) ((x) << S_PATH_MTU)
251#define F_PATH_MTU V_PATH_MTU(1U)
252
253#define S_5TUPLE_LOOKUP 17
254#define V_5TUPLE_LOOKUP(x) ((x) << S_5TUPLE_LOOKUP)
255
256#define S_SYN_COOKIE_PARAMETER 26
257#define V_SYN_COOKIE_PARAMETER(x) ((x) << S_SYN_COOKIE_PARAMETER)
258
259#define A_TP_PC_CONFIG 0x348
260#define S_DIS_TX_FILL_WIN_PUSH 12
261#define V_DIS_TX_FILL_WIN_PUSH(x) ((x) << S_DIS_TX_FILL_WIN_PUSH)
262#define F_DIS_TX_FILL_WIN_PUSH V_DIS_TX_FILL_WIN_PUSH(1U)
263
264#define S_TP_PC_REV 30
265#define M_TP_PC_REV 0x3
266#define G_TP_PC_REV(x) (((x) >> S_TP_PC_REV) & M_TP_PC_REV)
267#define A_TP_RESET 0x44c
268#define S_TP_RESET 0
269#define V_TP_RESET(x) ((x) << S_TP_RESET)
270#define F_TP_RESET V_TP_RESET(1U)
271
272#define A_TP_INT_ENABLE 0x470
273#define A_TP_INT_CAUSE 0x474
274#define A_TP_TX_DROP_CONFIG 0x4b8
275
276#define S_ENABLE_TX_DROP 31
277#define V_ENABLE_TX_DROP(x) ((x) << S_ENABLE_TX_DROP)
278#define F_ENABLE_TX_DROP V_ENABLE_TX_DROP(1U)
279
280#define S_ENABLE_TX_ERROR 30
281#define V_ENABLE_TX_ERROR(x) ((x) << S_ENABLE_TX_ERROR)
282#define F_ENABLE_TX_ERROR V_ENABLE_TX_ERROR(1U)
283
284#define S_DROP_TICKS_CNT 4
285#define V_DROP_TICKS_CNT(x) ((x) << S_DROP_TICKS_CNT)
286
287#define S_NUM_PKTS_DROPPED 0
288#define V_NUM_PKTS_DROPPED(x) ((x) << S_NUM_PKTS_DROPPED)
289
290/* CSPI registers */
291
292#define S_DIP4ERR 0
293#define V_DIP4ERR(x) ((x) << S_DIP4ERR)
294#define F_DIP4ERR V_DIP4ERR(1U)
295
296#define S_RXDROP 1
297#define V_RXDROP(x) ((x) << S_RXDROP)
298#define F_RXDROP V_RXDROP(1U)
299
300#define S_TXDROP 2
301#define V_TXDROP(x) ((x) << S_TXDROP)
302#define F_TXDROP V_TXDROP(1U)
303
304#define S_RXOVERFLOW 3
305#define V_RXOVERFLOW(x) ((x) << S_RXOVERFLOW)
306#define F_RXOVERFLOW V_RXOVERFLOW(1U)
307
308#define S_RAMPARITYERR 4
309#define V_RAMPARITYERR(x) ((x) << S_RAMPARITYERR)
310#define F_RAMPARITYERR V_RAMPARITYERR(1U)
311
312/* ESPI registers */
313
314#define A_ESPI_SCH_TOKEN0 0x880
315#define A_ESPI_SCH_TOKEN1 0x884
316#define A_ESPI_SCH_TOKEN2 0x888
317#define A_ESPI_SCH_TOKEN3 0x88c
318#define A_ESPI_RX_FIFO_ALMOST_EMPTY_WATERMARK 0x890
319#define A_ESPI_RX_FIFO_ALMOST_FULL_WATERMARK 0x894
320#define A_ESPI_CALENDAR_LENGTH 0x898
321#define A_PORT_CONFIG 0x89c
322
323#define S_RX_NPORTS 0
324#define V_RX_NPORTS(x) ((x) << S_RX_NPORTS)
325
326#define S_TX_NPORTS 8
327#define V_TX_NPORTS(x) ((x) << S_TX_NPORTS)
328
329#define A_ESPI_FIFO_STATUS_ENABLE 0x8a0
330
331#define S_RXSTATUSENABLE 0
332#define V_RXSTATUSENABLE(x) ((x) << S_RXSTATUSENABLE)
333#define F_RXSTATUSENABLE V_RXSTATUSENABLE(1U)
334
335#define S_INTEL1010MODE 4
336#define V_INTEL1010MODE(x) ((x) << S_INTEL1010MODE)
337#define F_INTEL1010MODE V_INTEL1010MODE(1U)
338
339#define A_ESPI_MAXBURST1_MAXBURST2 0x8a8
340#define A_ESPI_TRAIN 0x8ac
341#define A_ESPI_INTR_STATUS 0x8c8
342
343#define S_DIP2PARITYERR 5
344#define V_DIP2PARITYERR(x) ((x) << S_DIP2PARITYERR)
345#define F_DIP2PARITYERR V_DIP2PARITYERR(1U)
346
347#define A_ESPI_INTR_ENABLE 0x8cc
348#define A_RX_DROP_THRESHOLD 0x8d0
349#define A_ESPI_RX_RESET 0x8ec
350#define A_ESPI_MISC_CONTROL 0x8f0
351
352#define S_OUT_OF_SYNC_COUNT 0
353#define V_OUT_OF_SYNC_COUNT(x) ((x) << S_OUT_OF_SYNC_COUNT)
354
355#define S_DIP2_PARITY_ERR_THRES 5
356#define V_DIP2_PARITY_ERR_THRES(x) ((x) << S_DIP2_PARITY_ERR_THRES)
357
358#define S_DIP4_THRES 9
359#define V_DIP4_THRES(x) ((x) << S_DIP4_THRES)
360
361#define S_MONITORED_PORT_NUM 25
362#define V_MONITORED_PORT_NUM(x) ((x) << S_MONITORED_PORT_NUM)
363
364#define S_MONITORED_DIRECTION 27
365#define V_MONITORED_DIRECTION(x) ((x) << S_MONITORED_DIRECTION)
366#define F_MONITORED_DIRECTION V_MONITORED_DIRECTION(1U)
367
368#define S_MONITORED_INTERFACE 28
369#define V_MONITORED_INTERFACE(x) ((x) << S_MONITORED_INTERFACE)
370#define F_MONITORED_INTERFACE V_MONITORED_INTERFACE(1U)
371
372#define A_ESPI_DIP2_ERR_COUNT 0x8f4
373#define A_ESPI_CMD_ADDR 0x8f8
374
375#define S_WRITE_DATA 0
376#define V_WRITE_DATA(x) ((x) << S_WRITE_DATA)
377
378#define S_REGISTER_OFFSET 8
379#define V_REGISTER_OFFSET(x) ((x) << S_REGISTER_OFFSET)
380
381#define S_CHANNEL_ADDR 12
382#define V_CHANNEL_ADDR(x) ((x) << S_CHANNEL_ADDR)
383
384#define S_MODULE_ADDR 16
385#define V_MODULE_ADDR(x) ((x) << S_MODULE_ADDR)
386
387#define S_BUNDLE_ADDR 20
388#define V_BUNDLE_ADDR(x) ((x) << S_BUNDLE_ADDR)
389
390#define S_SPI4_COMMAND 24
391#define V_SPI4_COMMAND(x) ((x) << S_SPI4_COMMAND)
392
393#define A_ESPI_GOSTAT 0x8fc
394#define S_ESPI_CMD_BUSY 8
395#define V_ESPI_CMD_BUSY(x) ((x) << S_ESPI_CMD_BUSY)
396#define F_ESPI_CMD_BUSY V_ESPI_CMD_BUSY(1U)
397
398/* PL registers */
399
400#define A_PL_ENABLE 0xa00
401
402#define S_PL_INTR_SGE_ERR 0
403#define V_PL_INTR_SGE_ERR(x) ((x) << S_PL_INTR_SGE_ERR)
404#define F_PL_INTR_SGE_ERR V_PL_INTR_SGE_ERR(1U)
405
406#define S_PL_INTR_SGE_DATA 1
407#define V_PL_INTR_SGE_DATA(x) ((x) << S_PL_INTR_SGE_DATA)
408#define F_PL_INTR_SGE_DATA V_PL_INTR_SGE_DATA(1U)
409
410#define S_PL_INTR_TP 6
411#define V_PL_INTR_TP(x) ((x) << S_PL_INTR_TP)
412#define F_PL_INTR_TP V_PL_INTR_TP(1U)
413
414#define S_PL_INTR_ESPI 8
415#define V_PL_INTR_ESPI(x) ((x) << S_PL_INTR_ESPI)
416#define F_PL_INTR_ESPI V_PL_INTR_ESPI(1U)
417
418#define S_PL_INTR_PCIX 10
419#define V_PL_INTR_PCIX(x) ((x) << S_PL_INTR_PCIX)
420#define F_PL_INTR_PCIX V_PL_INTR_PCIX(1U)
421
422#define S_PL_INTR_EXT 11
423#define V_PL_INTR_EXT(x) ((x) << S_PL_INTR_EXT)
424#define F_PL_INTR_EXT V_PL_INTR_EXT(1U)
425
426#define A_PL_CAUSE 0xa04
427
428/* MC5 registers */
429
430#define A_MC5_CONFIG 0xc04
431
432#define S_TCAM_RESET 1
433#define V_TCAM_RESET(x) ((x) << S_TCAM_RESET)
434#define F_TCAM_RESET V_TCAM_RESET(1U)
435
436#define S_M_BUS_ENABLE 5
437#define V_M_BUS_ENABLE(x) ((x) << S_M_BUS_ENABLE)
438#define F_M_BUS_ENABLE V_M_BUS_ENABLE(1U)
439
440/* PCICFG registers */
441
442#define A_PCICFG_PM_CSR 0x44
443#define A_PCICFG_VPD_ADDR 0x4a
444
445#define S_VPD_OP_FLAG 15
446#define V_VPD_OP_FLAG(x) ((x) << S_VPD_OP_FLAG)
447#define F_VPD_OP_FLAG V_VPD_OP_FLAG(1U)
448
449#define A_PCICFG_VPD_DATA 0x4c
450
451#define A_PCICFG_INTR_ENABLE 0xf4
452#define A_PCICFG_INTR_CAUSE 0xf8
453
454#define A_PCICFG_MODE 0xfc
455
456#define S_PCI_MODE_64BIT 0
457#define V_PCI_MODE_64BIT(x) ((x) << S_PCI_MODE_64BIT)
458#define F_PCI_MODE_64BIT V_PCI_MODE_64BIT(1U)
459
460#define S_PCI_MODE_PCIX 5
461#define V_PCI_MODE_PCIX(x) ((x) << S_PCI_MODE_PCIX)
462#define F_PCI_MODE_PCIX V_PCI_MODE_PCIX(1U)
463
464#define S_PCI_MODE_CLK 6
465#define M_PCI_MODE_CLK 0x3
466#define G_PCI_MODE_CLK(x) (((x) >> S_PCI_MODE_CLK) & M_PCI_MODE_CLK)
467
468#endif /* _CXGB_REGS_H_ */
diff --git a/drivers/net/chelsio/sge.c b/drivers/net/chelsio/sge.c
new file mode 100644
index 000000000000..53b41d99b00b
--- /dev/null
+++ b/drivers/net/chelsio/sge.c
@@ -0,0 +1,1684 @@
1/*****************************************************************************
2 * *
3 * File: sge.c *
4 * $Revision: 1.26 $ *
5 * $Date: 2005/06/21 18:29:48 $ *
6 * Description: *
7 * DMA engine. *
8 * part of the Chelsio 10Gb Ethernet Driver. *
9 * *
10 * This program is free software; you can redistribute it and/or modify *
11 * it under the terms of the GNU General Public License, version 2, as *
12 * published by the Free Software Foundation. *
13 * *
14 * You should have received a copy of the GNU General Public License along *
15 * with this program; if not, write to the Free Software Foundation, Inc., *
16 * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
17 * *
18 * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED *
19 * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF *
20 * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. *
21 * *
22 * http://www.chelsio.com *
23 * *
24 * Copyright (c) 2003 - 2005 Chelsio Communications, Inc. *
25 * All rights reserved. *
26 * *
27 * Maintainers: maintainers@chelsio.com *
28 * *
29 * Authors: Dimitrios Michailidis <dm@chelsio.com> *
30 * Tina Yang <tainay@chelsio.com> *
31 * Felix Marti <felix@chelsio.com> *
32 * Scott Bardone <sbardone@chelsio.com> *
33 * Kurt Ottaway <kottaway@chelsio.com> *
34 * Frank DiMambro <frank@chelsio.com> *
35 * *
36 * History: *
37 * *
38 ****************************************************************************/
39
40#include "common.h"
41
42#include <linux/config.h>
43#include <linux/types.h>
44#include <linux/errno.h>
45#include <linux/pci.h>
46#include <linux/netdevice.h>
47#include <linux/etherdevice.h>
48#include <linux/if_vlan.h>
49#include <linux/skbuff.h>
50#include <linux/init.h>
51#include <linux/mm.h>
52#include <linux/ip.h>
53#include <linux/in.h>
54#include <linux/if_arp.h>
55
56#include "cpl5_cmd.h"
57#include "sge.h"
58#include "regs.h"
59#include "espi.h"
60
61
62#ifdef NETIF_F_TSO
63#include <linux/tcp.h>
64#endif
65
66#define SGE_CMDQ_N 2
67#define SGE_FREELQ_N 2
68#define SGE_CMDQ0_E_N 1024
69#define SGE_CMDQ1_E_N 128
70#define SGE_FREEL_SIZE 4096
71#define SGE_JUMBO_FREEL_SIZE 512
72#define SGE_FREEL_REFILL_THRESH 16
73#define SGE_RESPQ_E_N 1024
74#define SGE_INTRTIMER_NRES 1000
75#define SGE_RX_COPY_THRES 256
76#define SGE_RX_SM_BUF_SIZE 1536
77
78# define SGE_RX_DROP_THRES 2
79
80#define SGE_RESPQ_REPLENISH_THRES (SGE_RESPQ_E_N / 4)
81
82/*
83 * Period of the TX buffer reclaim timer. This timer does not need to run
84 * frequently as TX buffers are usually reclaimed by new TX packets.
85 */
86#define TX_RECLAIM_PERIOD (HZ / 4)
87
88#ifndef NET_IP_ALIGN
89# define NET_IP_ALIGN 2
90#endif
91
92#define M_CMD_LEN 0x7fffffff
93#define V_CMD_LEN(v) (v)
94#define G_CMD_LEN(v) ((v) & M_CMD_LEN)
95#define V_CMD_GEN1(v) ((v) << 31)
96#define V_CMD_GEN2(v) (v)
97#define F_CMD_DATAVALID (1 << 1)
98#define F_CMD_SOP (1 << 2)
99#define V_CMD_EOP(v) ((v) << 3)
100
101/*
102 * Command queue, receive buffer list, and response queue descriptors.
103 */
104#if defined(__BIG_ENDIAN_BITFIELD)
105struct cmdQ_e {
106 u32 addr_lo;
107 u32 len_gen;
108 u32 flags;
109 u32 addr_hi;
110};
111
112struct freelQ_e {
113 u32 addr_lo;
114 u32 len_gen;
115 u32 gen2;
116 u32 addr_hi;
117};
118
119struct respQ_e {
120 u32 Qsleeping : 4;
121 u32 Cmdq1CreditReturn : 5;
122 u32 Cmdq1DmaComplete : 5;
123 u32 Cmdq0CreditReturn : 5;
124 u32 Cmdq0DmaComplete : 5;
125 u32 FreelistQid : 2;
126 u32 CreditValid : 1;
127 u32 DataValid : 1;
128 u32 Offload : 1;
129 u32 Eop : 1;
130 u32 Sop : 1;
131 u32 GenerationBit : 1;
132 u32 BufferLength;
133};
134#elif defined(__LITTLE_ENDIAN_BITFIELD)
135struct cmdQ_e {
136 u32 len_gen;
137 u32 addr_lo;
138 u32 addr_hi;
139 u32 flags;
140};
141
142struct freelQ_e {
143 u32 len_gen;
144 u32 addr_lo;
145 u32 addr_hi;
146 u32 gen2;
147};
148
149struct respQ_e {
150 u32 BufferLength;
151 u32 GenerationBit : 1;
152 u32 Sop : 1;
153 u32 Eop : 1;
154 u32 Offload : 1;
155 u32 DataValid : 1;
156 u32 CreditValid : 1;
157 u32 FreelistQid : 2;
158 u32 Cmdq0DmaComplete : 5;
159 u32 Cmdq0CreditReturn : 5;
160 u32 Cmdq1DmaComplete : 5;
161 u32 Cmdq1CreditReturn : 5;
162 u32 Qsleeping : 4;
163} ;
164#endif
165
166/*
167 * SW Context Command and Freelist Queue Descriptors
168 */
169struct cmdQ_ce {
170 struct sk_buff *skb;
171 DECLARE_PCI_UNMAP_ADDR(dma_addr);
172 DECLARE_PCI_UNMAP_LEN(dma_len);
173};
174
175struct freelQ_ce {
176 struct sk_buff *skb;
177 DECLARE_PCI_UNMAP_ADDR(dma_addr);
178 DECLARE_PCI_UNMAP_LEN(dma_len);
179};
180
181/*
182 * SW command, freelist and response rings
183 */
184struct cmdQ {
185 unsigned long status; /* HW DMA fetch status */
186 unsigned int in_use; /* # of in-use command descriptors */
187 unsigned int size; /* # of descriptors */
188 unsigned int processed; /* total # of descs HW has processed */
189 unsigned int cleaned; /* total # of descs SW has reclaimed */
190 unsigned int stop_thres; /* SW TX queue suspend threshold */
191 u16 pidx; /* producer index (SW) */
192 u16 cidx; /* consumer index (HW) */
193 u8 genbit; /* current generation (=valid) bit */
194 u8 sop; /* is next entry start of packet? */
195 struct cmdQ_e *entries; /* HW command descriptor Q */
196 struct cmdQ_ce *centries; /* SW command context descriptor Q */
197 spinlock_t lock; /* Lock to protect cmdQ enqueuing */
198 dma_addr_t dma_addr; /* DMA addr HW command descriptor Q */
199};
200
201struct freelQ {
202 unsigned int credits; /* # of available RX buffers */
203 unsigned int size; /* free list capacity */
204 u16 pidx; /* producer index (SW) */
205 u16 cidx; /* consumer index (HW) */
206 u16 rx_buffer_size; /* Buffer size on this free list */
207 u16 dma_offset; /* DMA offset to align IP headers */
208 u16 recycleq_idx; /* skb recycle q to use */
209 u8 genbit; /* current generation (=valid) bit */
210 struct freelQ_e *entries; /* HW freelist descriptor Q */
211 struct freelQ_ce *centries; /* SW freelist context descriptor Q */
212 dma_addr_t dma_addr; /* DMA addr HW freelist descriptor Q */
213};
214
215struct respQ {
216 unsigned int credits; /* credits to be returned to SGE */
217 unsigned int size; /* # of response Q descriptors */
218 u16 cidx; /* consumer index (SW) */
219 u8 genbit; /* current generation(=valid) bit */
220 struct respQ_e *entries; /* HW response descriptor Q */
221 dma_addr_t dma_addr; /* DMA addr HW response descriptor Q */
222};
223
224/* Bit flags for cmdQ.status */
225enum {
226 CMDQ_STAT_RUNNING = 1, /* fetch engine is running */
227 CMDQ_STAT_LAST_PKT_DB = 2 /* last packet rung the doorbell */
228};
229
230/*
231 * Main SGE data structure
232 *
233 * Interrupts are handled by a single CPU and it is likely that on a MP system
234 * the application is migrated to another CPU. In that scenario, we try to
235 * seperate the RX(in irq context) and TX state in order to decrease memory
236 * contention.
237 */
238struct sge {
239 struct adapter *adapter; /* adapter backpointer */
240 struct net_device *netdev; /* netdevice backpointer */
241 struct freelQ freelQ[SGE_FREELQ_N]; /* buffer free lists */
242 struct respQ respQ; /* response Q */
243 unsigned long stopped_tx_queues; /* bitmap of suspended Tx queues */
244 unsigned int rx_pkt_pad; /* RX padding for L2 packets */
245 unsigned int jumbo_fl; /* jumbo freelist Q index */
246 unsigned int intrtimer_nres; /* no-resource interrupt timer */
247 unsigned int fixed_intrtimer;/* non-adaptive interrupt timer */
248 struct timer_list tx_reclaim_timer; /* reclaims TX buffers */
249 struct timer_list espibug_timer;
250 unsigned int espibug_timeout;
251 struct sk_buff *espibug_skb;
252 u32 sge_control; /* shadow value of sge control reg */
253 struct sge_intr_counts stats;
254 struct sge_port_stats port_stats[MAX_NPORTS];
255 struct cmdQ cmdQ[SGE_CMDQ_N] ____cacheline_aligned_in_smp;
256};
257
258/*
259 * PIO to indicate that memory mapped Q contains valid descriptor(s).
260 */
261static inline void doorbell_pio(struct adapter *adapter, u32 val)
262{
263 wmb();
264 writel(val, adapter->regs + A_SG_DOORBELL);
265}
266
267/*
268 * Frees all RX buffers on the freelist Q. The caller must make sure that
269 * the SGE is turned off before calling this function.
270 */
271static void free_freelQ_buffers(struct pci_dev *pdev, struct freelQ *q)
272{
273 unsigned int cidx = q->cidx;
274
275 while (q->credits--) {
276 struct freelQ_ce *ce = &q->centries[cidx];
277
278 pci_unmap_single(pdev, pci_unmap_addr(ce, dma_addr),
279 pci_unmap_len(ce, dma_len),
280 PCI_DMA_FROMDEVICE);
281 dev_kfree_skb(ce->skb);
282 ce->skb = NULL;
283 if (++cidx == q->size)
284 cidx = 0;
285 }
286}
287
288/*
289 * Free RX free list and response queue resources.
290 */
291static void free_rx_resources(struct sge *sge)
292{
293 struct pci_dev *pdev = sge->adapter->pdev;
294 unsigned int size, i;
295
296 if (sge->respQ.entries) {
297 size = sizeof(struct respQ_e) * sge->respQ.size;
298 pci_free_consistent(pdev, size, sge->respQ.entries,
299 sge->respQ.dma_addr);
300 }
301
302 for (i = 0; i < SGE_FREELQ_N; i++) {
303 struct freelQ *q = &sge->freelQ[i];
304
305 if (q->centries) {
306 free_freelQ_buffers(pdev, q);
307 kfree(q->centries);
308 }
309 if (q->entries) {
310 size = sizeof(struct freelQ_e) * q->size;
311 pci_free_consistent(pdev, size, q->entries,
312 q->dma_addr);
313 }
314 }
315}
316
317/*
318 * Allocates basic RX resources, consisting of memory mapped freelist Qs and a
319 * response queue.
320 */
321static int alloc_rx_resources(struct sge *sge, struct sge_params *p)
322{
323 struct pci_dev *pdev = sge->adapter->pdev;
324 unsigned int size, i;
325
326 for (i = 0; i < SGE_FREELQ_N; i++) {
327 struct freelQ *q = &sge->freelQ[i];
328
329 q->genbit = 1;
330 q->size = p->freelQ_size[i];
331 q->dma_offset = sge->rx_pkt_pad ? 0 : NET_IP_ALIGN;
332 size = sizeof(struct freelQ_e) * q->size;
333 q->entries = (struct freelQ_e *)
334 pci_alloc_consistent(pdev, size, &q->dma_addr);
335 if (!q->entries)
336 goto err_no_mem;
337 memset(q->entries, 0, size);
338 size = sizeof(struct freelQ_ce) * q->size;
339 q->centries = kmalloc(size, GFP_KERNEL);
340 if (!q->centries)
341 goto err_no_mem;
342 memset(q->centries, 0, size);
343 }
344
345 /*
346 * Calculate the buffer sizes for the two free lists. FL0 accommodates
347 * regular sized Ethernet frames, FL1 is sized not to exceed 16K,
348 * including all the sk_buff overhead.
349 *
350 * Note: For T2 FL0 and FL1 are reversed.
351 */
352 sge->freelQ[!sge->jumbo_fl].rx_buffer_size = SGE_RX_SM_BUF_SIZE +
353 sizeof(struct cpl_rx_data) +
354 sge->freelQ[!sge->jumbo_fl].dma_offset;
355 sge->freelQ[sge->jumbo_fl].rx_buffer_size = (16 * 1024) -
356 SKB_DATA_ALIGN(sizeof(struct skb_shared_info));
357
358 /*
359 * Setup which skb recycle Q should be used when recycling buffers from
360 * each free list.
361 */
362 sge->freelQ[!sge->jumbo_fl].recycleq_idx = 0;
363 sge->freelQ[sge->jumbo_fl].recycleq_idx = 1;
364
365 sge->respQ.genbit = 1;
366 sge->respQ.size = SGE_RESPQ_E_N;
367 sge->respQ.credits = 0;
368 size = sizeof(struct respQ_e) * sge->respQ.size;
369 sge->respQ.entries = (struct respQ_e *)
370 pci_alloc_consistent(pdev, size, &sge->respQ.dma_addr);
371 if (!sge->respQ.entries)
372 goto err_no_mem;
373 memset(sge->respQ.entries, 0, size);
374 return 0;
375
376err_no_mem:
377 free_rx_resources(sge);
378 return -ENOMEM;
379}
380
381/*
382 * Reclaims n TX descriptors and frees the buffers associated with them.
383 */
384static void free_cmdQ_buffers(struct sge *sge, struct cmdQ *q, unsigned int n)
385{
386 struct cmdQ_ce *ce;
387 struct pci_dev *pdev = sge->adapter->pdev;
388 unsigned int cidx = q->cidx;
389
390 q->in_use -= n;
391 ce = &q->centries[cidx];
392 while (n--) {
393 if (q->sop)
394 pci_unmap_single(pdev, pci_unmap_addr(ce, dma_addr),
395 pci_unmap_len(ce, dma_len),
396 PCI_DMA_TODEVICE);
397 else
398 pci_unmap_page(pdev, pci_unmap_addr(ce, dma_addr),
399 pci_unmap_len(ce, dma_len),
400 PCI_DMA_TODEVICE);
401 q->sop = 0;
402 if (ce->skb) {
403 dev_kfree_skb(ce->skb);
404 q->sop = 1;
405 }
406 ce++;
407 if (++cidx == q->size) {
408 cidx = 0;
409 ce = q->centries;
410 }
411 }
412 q->cidx = cidx;
413}
414
415/*
416 * Free TX resources.
417 *
418 * Assumes that SGE is stopped and all interrupts are disabled.
419 */
420static void free_tx_resources(struct sge *sge)
421{
422 struct pci_dev *pdev = sge->adapter->pdev;
423 unsigned int size, i;
424
425 for (i = 0; i < SGE_CMDQ_N; i++) {
426 struct cmdQ *q = &sge->cmdQ[i];
427
428 if (q->centries) {
429 if (q->in_use)
430 free_cmdQ_buffers(sge, q, q->in_use);
431 kfree(q->centries);
432 }
433 if (q->entries) {
434 size = sizeof(struct cmdQ_e) * q->size;
435 pci_free_consistent(pdev, size, q->entries,
436 q->dma_addr);
437 }
438 }
439}
440
441/*
442 * Allocates basic TX resources, consisting of memory mapped command Qs.
443 */
444static int alloc_tx_resources(struct sge *sge, struct sge_params *p)
445{
446 struct pci_dev *pdev = sge->adapter->pdev;
447 unsigned int size, i;
448
449 for (i = 0; i < SGE_CMDQ_N; i++) {
450 struct cmdQ *q = &sge->cmdQ[i];
451
452 q->genbit = 1;
453 q->sop = 1;
454 q->size = p->cmdQ_size[i];
455 q->in_use = 0;
456 q->status = 0;
457 q->processed = q->cleaned = 0;
458 q->stop_thres = 0;
459 spin_lock_init(&q->lock);
460 size = sizeof(struct cmdQ_e) * q->size;
461 q->entries = (struct cmdQ_e *)
462 pci_alloc_consistent(pdev, size, &q->dma_addr);
463 if (!q->entries)
464 goto err_no_mem;
465 memset(q->entries, 0, size);
466 size = sizeof(struct cmdQ_ce) * q->size;
467 q->centries = kmalloc(size, GFP_KERNEL);
468 if (!q->centries)
469 goto err_no_mem;
470 memset(q->centries, 0, size);
471 }
472
473 /*
474 * CommandQ 0 handles Ethernet and TOE packets, while queue 1 is TOE
475 * only. For queue 0 set the stop threshold so we can handle one more
476 * packet from each port, plus reserve an additional 24 entries for
477 * Ethernet packets only. Queue 1 never suspends nor do we reserve
478 * space for Ethernet packets.
479 */
480 sge->cmdQ[0].stop_thres = sge->adapter->params.nports *
481 (MAX_SKB_FRAGS + 1);
482 return 0;
483
484err_no_mem:
485 free_tx_resources(sge);
486 return -ENOMEM;
487}
488
489static inline void setup_ring_params(struct adapter *adapter, u64 addr,
490 u32 size, int base_reg_lo,
491 int base_reg_hi, int size_reg)
492{
493 writel((u32)addr, adapter->regs + base_reg_lo);
494 writel(addr >> 32, adapter->regs + base_reg_hi);
495 writel(size, adapter->regs + size_reg);
496}
497
498/*
499 * Enable/disable VLAN acceleration.
500 */
501void t1_set_vlan_accel(struct adapter *adapter, int on_off)
502{
503 struct sge *sge = adapter->sge;
504
505 sge->sge_control &= ~F_VLAN_XTRACT;
506 if (on_off)
507 sge->sge_control |= F_VLAN_XTRACT;
508 if (adapter->open_device_map) {
509 writel(sge->sge_control, adapter->regs + A_SG_CONTROL);
510 readl(adapter->regs + A_SG_CONTROL); /* flush */
511 }
512}
513
514/*
515 * Programs the various SGE registers. However, the engine is not yet enabled,
516 * but sge->sge_control is setup and ready to go.
517 */
518static void configure_sge(struct sge *sge, struct sge_params *p)
519{
520 struct adapter *ap = sge->adapter;
521
522 writel(0, ap->regs + A_SG_CONTROL);
523 setup_ring_params(ap, sge->cmdQ[0].dma_addr, sge->cmdQ[0].size,
524 A_SG_CMD0BASELWR, A_SG_CMD0BASEUPR, A_SG_CMD0SIZE);
525 setup_ring_params(ap, sge->cmdQ[1].dma_addr, sge->cmdQ[1].size,
526 A_SG_CMD1BASELWR, A_SG_CMD1BASEUPR, A_SG_CMD1SIZE);
527 setup_ring_params(ap, sge->freelQ[0].dma_addr,
528 sge->freelQ[0].size, A_SG_FL0BASELWR,
529 A_SG_FL0BASEUPR, A_SG_FL0SIZE);
530 setup_ring_params(ap, sge->freelQ[1].dma_addr,
531 sge->freelQ[1].size, A_SG_FL1BASELWR,
532 A_SG_FL1BASEUPR, A_SG_FL1SIZE);
533
534 /* The threshold comparison uses <. */
535 writel(SGE_RX_SM_BUF_SIZE + 1, ap->regs + A_SG_FLTHRESHOLD);
536
537 setup_ring_params(ap, sge->respQ.dma_addr, sge->respQ.size,
538 A_SG_RSPBASELWR, A_SG_RSPBASEUPR, A_SG_RSPSIZE);
539 writel((u32)sge->respQ.size - 1, ap->regs + A_SG_RSPQUEUECREDIT);
540
541 sge->sge_control = F_CMDQ0_ENABLE | F_CMDQ1_ENABLE | F_FL0_ENABLE |
542 F_FL1_ENABLE | F_CPL_ENABLE | F_RESPONSE_QUEUE_ENABLE |
543 V_CMDQ_PRIORITY(2) | F_DISABLE_CMDQ1_GTS | F_ISCSI_COALESCE |
544 F_DISABLE_FL0_GTS | F_DISABLE_FL1_GTS |
545 V_RX_PKT_OFFSET(sge->rx_pkt_pad);
546
547#if defined(__BIG_ENDIAN_BITFIELD)
548 sge->sge_control |= F_ENABLE_BIG_ENDIAN;
549#endif
550
551 /* Initialize no-resource timer */
552 sge->intrtimer_nres = SGE_INTRTIMER_NRES * core_ticks_per_usec(ap);
553
554 t1_sge_set_coalesce_params(sge, p);
555}
556
557/*
558 * Return the payload capacity of the jumbo free-list buffers.
559 */
560static inline unsigned int jumbo_payload_capacity(const struct sge *sge)
561{
562 return sge->freelQ[sge->jumbo_fl].rx_buffer_size -
563 sge->freelQ[sge->jumbo_fl].dma_offset -
564 sizeof(struct cpl_rx_data);
565}
566
567/*
568 * Frees all SGE related resources and the sge structure itself
569 */
570void t1_sge_destroy(struct sge *sge)
571{
572 if (sge->espibug_skb)
573 kfree_skb(sge->espibug_skb);
574
575 free_tx_resources(sge);
576 free_rx_resources(sge);
577 kfree(sge);
578}
579
580/*
581 * Allocates new RX buffers on the freelist Q (and tracks them on the freelist
582 * context Q) until the Q is full or alloc_skb fails.
583 *
584 * It is possible that the generation bits already match, indicating that the
585 * buffer is already valid and nothing needs to be done. This happens when we
586 * copied a received buffer into a new sk_buff during the interrupt processing.
587 *
588 * If the SGE doesn't automatically align packets properly (!sge->rx_pkt_pad),
589 * we specify a RX_OFFSET in order to make sure that the IP header is 4B
590 * aligned.
591 */
592static void refill_free_list(struct sge *sge, struct freelQ *q)
593{
594 struct pci_dev *pdev = sge->adapter->pdev;
595 struct freelQ_ce *ce = &q->centries[q->pidx];
596 struct freelQ_e *e = &q->entries[q->pidx];
597 unsigned int dma_len = q->rx_buffer_size - q->dma_offset;
598
599
600 while (q->credits < q->size) {
601 struct sk_buff *skb;
602 dma_addr_t mapping;
603
604 skb = alloc_skb(q->rx_buffer_size, GFP_ATOMIC);
605 if (!skb)
606 break;
607
608 skb_reserve(skb, q->dma_offset);
609 mapping = pci_map_single(pdev, skb->data, dma_len,
610 PCI_DMA_FROMDEVICE);
611 ce->skb = skb;
612 pci_unmap_addr_set(ce, dma_addr, mapping);
613 pci_unmap_len_set(ce, dma_len, dma_len);
614 e->addr_lo = (u32)mapping;
615 e->addr_hi = (u64)mapping >> 32;
616 e->len_gen = V_CMD_LEN(dma_len) | V_CMD_GEN1(q->genbit);
617 wmb();
618 e->gen2 = V_CMD_GEN2(q->genbit);
619
620 e++;
621 ce++;
622 if (++q->pidx == q->size) {
623 q->pidx = 0;
624 q->genbit ^= 1;
625 ce = q->centries;
626 e = q->entries;
627 }
628 q->credits++;
629 }
630
631}
632
633/*
634 * Calls refill_free_list for both free lists. If we cannot fill at least 1/4
635 * of both rings, we go into 'few interrupt mode' in order to give the system
636 * time to free up resources.
637 */
638static void freelQs_empty(struct sge *sge)
639{
640 struct adapter *adapter = sge->adapter;
641 u32 irq_reg = readl(adapter->regs + A_SG_INT_ENABLE);
642 u32 irqholdoff_reg;
643
644 refill_free_list(sge, &sge->freelQ[0]);
645 refill_free_list(sge, &sge->freelQ[1]);
646
647 if (sge->freelQ[0].credits > (sge->freelQ[0].size >> 2) &&
648 sge->freelQ[1].credits > (sge->freelQ[1].size >> 2)) {
649 irq_reg |= F_FL_EXHAUSTED;
650 irqholdoff_reg = sge->fixed_intrtimer;
651 } else {
652 /* Clear the F_FL_EXHAUSTED interrupts for now */
653 irq_reg &= ~F_FL_EXHAUSTED;
654 irqholdoff_reg = sge->intrtimer_nres;
655 }
656 writel(irqholdoff_reg, adapter->regs + A_SG_INTRTIMER);
657 writel(irq_reg, adapter->regs + A_SG_INT_ENABLE);
658
659 /* We reenable the Qs to force a freelist GTS interrupt later */
660 doorbell_pio(adapter, F_FL0_ENABLE | F_FL1_ENABLE);
661}
662
663#define SGE_PL_INTR_MASK (F_PL_INTR_SGE_ERR | F_PL_INTR_SGE_DATA)
664#define SGE_INT_FATAL (F_RESPQ_OVERFLOW | F_PACKET_TOO_BIG | F_PACKET_MISMATCH)
665#define SGE_INT_ENABLE (F_RESPQ_EXHAUSTED | F_RESPQ_OVERFLOW | \
666 F_FL_EXHAUSTED | F_PACKET_TOO_BIG | F_PACKET_MISMATCH)
667
668/*
669 * Disable SGE Interrupts
670 */
671void t1_sge_intr_disable(struct sge *sge)
672{
673 u32 val = readl(sge->adapter->regs + A_PL_ENABLE);
674
675 writel(val & ~SGE_PL_INTR_MASK, sge->adapter->regs + A_PL_ENABLE);
676 writel(0, sge->adapter->regs + A_SG_INT_ENABLE);
677}
678
679/*
680 * Enable SGE interrupts.
681 */
682void t1_sge_intr_enable(struct sge *sge)
683{
684 u32 en = SGE_INT_ENABLE;
685 u32 val = readl(sge->adapter->regs + A_PL_ENABLE);
686
687 if (sge->adapter->flags & TSO_CAPABLE)
688 en &= ~F_PACKET_TOO_BIG;
689 writel(en, sge->adapter->regs + A_SG_INT_ENABLE);
690 writel(val | SGE_PL_INTR_MASK, sge->adapter->regs + A_PL_ENABLE);
691}
692
693/*
694 * Clear SGE interrupts.
695 */
696void t1_sge_intr_clear(struct sge *sge)
697{
698 writel(SGE_PL_INTR_MASK, sge->adapter->regs + A_PL_CAUSE);
699 writel(0xffffffff, sge->adapter->regs + A_SG_INT_CAUSE);
700}
701
702/*
703 * SGE 'Error' interrupt handler
704 */
705int t1_sge_intr_error_handler(struct sge *sge)
706{
707 struct adapter *adapter = sge->adapter;
708 u32 cause = readl(adapter->regs + A_SG_INT_CAUSE);
709
710 if (adapter->flags & TSO_CAPABLE)
711 cause &= ~F_PACKET_TOO_BIG;
712 if (cause & F_RESPQ_EXHAUSTED)
713 sge->stats.respQ_empty++;
714 if (cause & F_RESPQ_OVERFLOW) {
715 sge->stats.respQ_overflow++;
716 CH_ALERT("%s: SGE response queue overflow\n",
717 adapter->name);
718 }
719 if (cause & F_FL_EXHAUSTED) {
720 sge->stats.freelistQ_empty++;
721 freelQs_empty(sge);
722 }
723 if (cause & F_PACKET_TOO_BIG) {
724 sge->stats.pkt_too_big++;
725 CH_ALERT("%s: SGE max packet size exceeded\n",
726 adapter->name);
727 }
728 if (cause & F_PACKET_MISMATCH) {
729 sge->stats.pkt_mismatch++;
730 CH_ALERT("%s: SGE packet mismatch\n", adapter->name);
731 }
732 if (cause & SGE_INT_FATAL)
733 t1_fatal_err(adapter);
734
735 writel(cause, adapter->regs + A_SG_INT_CAUSE);
736 return 0;
737}
738
739const struct sge_intr_counts *t1_sge_get_intr_counts(struct sge *sge)
740{
741 return &sge->stats;
742}
743
744const struct sge_port_stats *t1_sge_get_port_stats(struct sge *sge, int port)
745{
746 return &sge->port_stats[port];
747}
748
749/**
750 * recycle_fl_buf - recycle a free list buffer
751 * @fl: the free list
752 * @idx: index of buffer to recycle
753 *
754 * Recycles the specified buffer on the given free list by adding it at
755 * the next available slot on the list.
756 */
757static void recycle_fl_buf(struct freelQ *fl, int idx)
758{
759 struct freelQ_e *from = &fl->entries[idx];
760 struct freelQ_e *to = &fl->entries[fl->pidx];
761
762 fl->centries[fl->pidx] = fl->centries[idx];
763 to->addr_lo = from->addr_lo;
764 to->addr_hi = from->addr_hi;
765 to->len_gen = G_CMD_LEN(from->len_gen) | V_CMD_GEN1(fl->genbit);
766 wmb();
767 to->gen2 = V_CMD_GEN2(fl->genbit);
768 fl->credits++;
769
770 if (++fl->pidx == fl->size) {
771 fl->pidx = 0;
772 fl->genbit ^= 1;
773 }
774}
775
776/**
777 * get_packet - return the next ingress packet buffer
778 * @pdev: the PCI device that received the packet
779 * @fl: the SGE free list holding the packet
780 * @len: the actual packet length, excluding any SGE padding
781 * @dma_pad: padding at beginning of buffer left by SGE DMA
782 * @skb_pad: padding to be used if the packet is copied
783 * @copy_thres: length threshold under which a packet should be copied
784 * @drop_thres: # of remaining buffers before we start dropping packets
785 *
786 * Get the next packet from a free list and complete setup of the
787 * sk_buff. If the packet is small we make a copy and recycle the
788 * original buffer, otherwise we use the original buffer itself. If a
789 * positive drop threshold is supplied packets are dropped and their
790 * buffers recycled if (a) the number of remaining buffers is under the
791 * threshold and the packet is too big to copy, or (b) the packet should
792 * be copied but there is no memory for the copy.
793 */
794static inline struct sk_buff *get_packet(struct pci_dev *pdev,
795 struct freelQ *fl, unsigned int len,
796 int dma_pad, int skb_pad,
797 unsigned int copy_thres,
798 unsigned int drop_thres)
799{
800 struct sk_buff *skb;
801 struct freelQ_ce *ce = &fl->centries[fl->cidx];
802
803 if (len < copy_thres) {
804 skb = alloc_skb(len + skb_pad, GFP_ATOMIC);
805 if (likely(skb != NULL)) {
806 skb_reserve(skb, skb_pad);
807 skb_put(skb, len);
808 pci_dma_sync_single_for_cpu(pdev,
809 pci_unmap_addr(ce, dma_addr),
810 pci_unmap_len(ce, dma_len),
811 PCI_DMA_FROMDEVICE);
812 memcpy(skb->data, ce->skb->data + dma_pad, len);
813 pci_dma_sync_single_for_device(pdev,
814 pci_unmap_addr(ce, dma_addr),
815 pci_unmap_len(ce, dma_len),
816 PCI_DMA_FROMDEVICE);
817 } else if (!drop_thres)
818 goto use_orig_buf;
819
820 recycle_fl_buf(fl, fl->cidx);
821 return skb;
822 }
823
824 if (fl->credits < drop_thres) {
825 recycle_fl_buf(fl, fl->cidx);
826 return NULL;
827 }
828
829use_orig_buf:
830 pci_unmap_single(pdev, pci_unmap_addr(ce, dma_addr),
831 pci_unmap_len(ce, dma_len), PCI_DMA_FROMDEVICE);
832 skb = ce->skb;
833 skb_reserve(skb, dma_pad);
834 skb_put(skb, len);
835 return skb;
836}
837
838/**
839 * unexpected_offload - handle an unexpected offload packet
840 * @adapter: the adapter
841 * @fl: the free list that received the packet
842 *
843 * Called when we receive an unexpected offload packet (e.g., the TOE
844 * function is disabled or the card is a NIC). Prints a message and
845 * recycles the buffer.
846 */
847static void unexpected_offload(struct adapter *adapter, struct freelQ *fl)
848{
849 struct freelQ_ce *ce = &fl->centries[fl->cidx];
850 struct sk_buff *skb = ce->skb;
851
852 pci_dma_sync_single_for_cpu(adapter->pdev, pci_unmap_addr(ce, dma_addr),
853 pci_unmap_len(ce, dma_len), PCI_DMA_FROMDEVICE);
854 CH_ERR("%s: unexpected offload packet, cmd %u\n",
855 adapter->name, *skb->data);
856 recycle_fl_buf(fl, fl->cidx);
857}
858
859/*
860 * Write the command descriptors to transmit the given skb starting at
861 * descriptor pidx with the given generation.
862 */
863static inline void write_tx_descs(struct adapter *adapter, struct sk_buff *skb,
864 unsigned int pidx, unsigned int gen,
865 struct cmdQ *q)
866{
867 dma_addr_t mapping;
868 struct cmdQ_e *e, *e1;
869 struct cmdQ_ce *ce;
870 unsigned int i, flags, nfrags = skb_shinfo(skb)->nr_frags;
871
872 mapping = pci_map_single(adapter->pdev, skb->data,
873 skb->len - skb->data_len, PCI_DMA_TODEVICE);
874 ce = &q->centries[pidx];
875 ce->skb = NULL;
876 pci_unmap_addr_set(ce, dma_addr, mapping);
877 pci_unmap_len_set(ce, dma_len, skb->len - skb->data_len);
878
879 flags = F_CMD_DATAVALID | F_CMD_SOP | V_CMD_EOP(nfrags == 0) |
880 V_CMD_GEN2(gen);
881 e = &q->entries[pidx];
882 e->addr_lo = (u32)mapping;
883 e->addr_hi = (u64)mapping >> 32;
884 e->len_gen = V_CMD_LEN(skb->len - skb->data_len) | V_CMD_GEN1(gen);
885 for (e1 = e, i = 0; nfrags--; i++) {
886 skb_frag_t *frag = &skb_shinfo(skb)->frags[i];
887
888 ce++;
889 e1++;
890 if (++pidx == q->size) {
891 pidx = 0;
892 gen ^= 1;
893 ce = q->centries;
894 e1 = q->entries;
895 }
896
897 mapping = pci_map_page(adapter->pdev, frag->page,
898 frag->page_offset, frag->size,
899 PCI_DMA_TODEVICE);
900 ce->skb = NULL;
901 pci_unmap_addr_set(ce, dma_addr, mapping);
902 pci_unmap_len_set(ce, dma_len, frag->size);
903
904 e1->addr_lo = (u32)mapping;
905 e1->addr_hi = (u64)mapping >> 32;
906 e1->len_gen = V_CMD_LEN(frag->size) | V_CMD_GEN1(gen);
907 e1->flags = F_CMD_DATAVALID | V_CMD_EOP(nfrags == 0) |
908 V_CMD_GEN2(gen);
909 }
910
911 ce->skb = skb;
912 wmb();
913 e->flags = flags;
914}
915
916/*
917 * Clean up completed Tx buffers.
918 */
919static inline void reclaim_completed_tx(struct sge *sge, struct cmdQ *q)
920{
921 unsigned int reclaim = q->processed - q->cleaned;
922
923 if (reclaim) {
924 free_cmdQ_buffers(sge, q, reclaim);
925 q->cleaned += reclaim;
926 }
927}
928
929#ifndef SET_ETHTOOL_OPS
930# define __netif_rx_complete(dev) netif_rx_complete(dev)
931#endif
932
933/*
934 * We cannot use the standard netif_rx_schedule_prep() because we have multiple
935 * ports plus the TOE all multiplexing onto a single response queue, therefore
936 * accepting new responses cannot depend on the state of any particular port.
937 * So define our own equivalent that omits the netif_running() test.
938 */
939static inline int napi_schedule_prep(struct net_device *dev)
940{
941 return !test_and_set_bit(__LINK_STATE_RX_SCHED, &dev->state);
942}
943
944
945/**
946 * sge_rx - process an ingress ethernet packet
947 * @sge: the sge structure
948 * @fl: the free list that contains the packet buffer
949 * @len: the packet length
950 *
951 * Process an ingress ethernet pakcet and deliver it to the stack.
952 */
953static int sge_rx(struct sge *sge, struct freelQ *fl, unsigned int len)
954{
955 struct sk_buff *skb;
956 struct cpl_rx_pkt *p;
957 struct adapter *adapter = sge->adapter;
958
959 sge->stats.ethernet_pkts++;
960 skb = get_packet(adapter->pdev, fl, len - sge->rx_pkt_pad,
961 sge->rx_pkt_pad, 2, SGE_RX_COPY_THRES,
962 SGE_RX_DROP_THRES);
963 if (!skb) {
964 sge->port_stats[0].rx_drops++; /* charge only port 0 for now */
965 return 0;
966 }
967
968 p = (struct cpl_rx_pkt *)skb->data;
969 skb_pull(skb, sizeof(*p));
970 skb->dev = adapter->port[p->iff].dev;
971 skb->dev->last_rx = jiffies;
972 skb->protocol = eth_type_trans(skb, skb->dev);
973 if ((adapter->flags & RX_CSUM_ENABLED) && p->csum == 0xffff &&
974 skb->protocol == htons(ETH_P_IP) &&
975 (skb->data[9] == IPPROTO_TCP || skb->data[9] == IPPROTO_UDP)) {
976 sge->port_stats[p->iff].rx_cso_good++;
977 skb->ip_summed = CHECKSUM_UNNECESSARY;
978 } else
979 skb->ip_summed = CHECKSUM_NONE;
980
981 if (unlikely(adapter->vlan_grp && p->vlan_valid)) {
982 sge->port_stats[p->iff].vlan_xtract++;
983 if (adapter->params.sge.polling)
984 vlan_hwaccel_receive_skb(skb, adapter->vlan_grp,
985 ntohs(p->vlan));
986 else
987 vlan_hwaccel_rx(skb, adapter->vlan_grp,
988 ntohs(p->vlan));
989 } else if (adapter->params.sge.polling)
990 netif_receive_skb(skb);
991 else
992 netif_rx(skb);
993 return 0;
994}
995
996/*
997 * Returns true if a command queue has enough available descriptors that
998 * we can resume Tx operation after temporarily disabling its packet queue.
999 */
1000static inline int enough_free_Tx_descs(const struct cmdQ *q)
1001{
1002 unsigned int r = q->processed - q->cleaned;
1003
1004 return q->in_use - r < (q->size >> 1);
1005}
1006
1007/*
1008 * Called when sufficient space has become available in the SGE command queues
1009 * after the Tx packet schedulers have been suspended to restart the Tx path.
1010 */
1011static void restart_tx_queues(struct sge *sge)
1012{
1013 struct adapter *adap = sge->adapter;
1014
1015 if (enough_free_Tx_descs(&sge->cmdQ[0])) {
1016 int i;
1017
1018 for_each_port(adap, i) {
1019 struct net_device *nd = adap->port[i].dev;
1020
1021 if (test_and_clear_bit(nd->if_port,
1022 &sge->stopped_tx_queues) &&
1023 netif_running(nd)) {
1024 sge->stats.cmdQ_restarted[3]++;
1025 netif_wake_queue(nd);
1026 }
1027 }
1028 }
1029}
1030
1031/*
1032 * update_tx_info is called from the interrupt handler/NAPI to return cmdQ0
1033 * information.
1034 */
1035static unsigned int update_tx_info(struct adapter *adapter,
1036 unsigned int flags,
1037 unsigned int pr0)
1038{
1039 struct sge *sge = adapter->sge;
1040 struct cmdQ *cmdq = &sge->cmdQ[0];
1041
1042 cmdq->processed += pr0;
1043
1044 if (flags & F_CMDQ0_ENABLE) {
1045 clear_bit(CMDQ_STAT_RUNNING, &cmdq->status);
1046
1047 if (cmdq->cleaned + cmdq->in_use != cmdq->processed &&
1048 !test_and_set_bit(CMDQ_STAT_LAST_PKT_DB, &cmdq->status)) {
1049 set_bit(CMDQ_STAT_RUNNING, &cmdq->status);
1050 writel(F_CMDQ0_ENABLE, adapter->regs + A_SG_DOORBELL);
1051 }
1052 flags &= ~F_CMDQ0_ENABLE;
1053 }
1054
1055 if (unlikely(sge->stopped_tx_queues != 0))
1056 restart_tx_queues(sge);
1057
1058 return flags;
1059}
1060
1061/*
1062 * Process SGE responses, up to the supplied budget. Returns the number of
1063 * responses processed. A negative budget is effectively unlimited.
1064 */
1065static int process_responses(struct adapter *adapter, int budget)
1066{
1067 struct sge *sge = adapter->sge;
1068 struct respQ *q = &sge->respQ;
1069 struct respQ_e *e = &q->entries[q->cidx];
1070 int budget_left = budget;
1071 unsigned int flags = 0;
1072 unsigned int cmdq_processed[SGE_CMDQ_N] = {0, 0};
1073
1074
1075 while (likely(budget_left && e->GenerationBit == q->genbit)) {
1076 flags |= e->Qsleeping;
1077
1078 cmdq_processed[0] += e->Cmdq0CreditReturn;
1079 cmdq_processed[1] += e->Cmdq1CreditReturn;
1080
1081 /* We batch updates to the TX side to avoid cacheline
1082 * ping-pong of TX state information on MP where the sender
1083 * might run on a different CPU than this function...
1084 */
1085 if (unlikely(flags & F_CMDQ0_ENABLE || cmdq_processed[0] > 64)) {
1086 flags = update_tx_info(adapter, flags, cmdq_processed[0]);
1087 cmdq_processed[0] = 0;
1088 }
1089 if (unlikely(cmdq_processed[1] > 16)) {
1090 sge->cmdQ[1].processed += cmdq_processed[1];
1091 cmdq_processed[1] = 0;
1092 }
1093 if (likely(e->DataValid)) {
1094 struct freelQ *fl = &sge->freelQ[e->FreelistQid];
1095
1096 if (unlikely(!e->Sop || !e->Eop))
1097 BUG();
1098 if (unlikely(e->Offload))
1099 unexpected_offload(adapter, fl);
1100 else
1101 sge_rx(sge, fl, e->BufferLength);
1102
1103 /*
1104 * Note: this depends on each packet consuming a
1105 * single free-list buffer; cf. the BUG above.
1106 */
1107 if (++fl->cidx == fl->size)
1108 fl->cidx = 0;
1109 if (unlikely(--fl->credits <
1110 fl->size - SGE_FREEL_REFILL_THRESH))
1111 refill_free_list(sge, fl);
1112 } else
1113 sge->stats.pure_rsps++;
1114
1115 e++;
1116 if (unlikely(++q->cidx == q->size)) {
1117 q->cidx = 0;
1118 q->genbit ^= 1;
1119 e = q->entries;
1120 }
1121 prefetch(e);
1122
1123 if (++q->credits > SGE_RESPQ_REPLENISH_THRES) {
1124 writel(q->credits, adapter->regs + A_SG_RSPQUEUECREDIT);
1125 q->credits = 0;
1126 }
1127 --budget_left;
1128 }
1129
1130 flags = update_tx_info(adapter, flags, cmdq_processed[0]);
1131 sge->cmdQ[1].processed += cmdq_processed[1];
1132
1133 budget -= budget_left;
1134 return budget;
1135}
1136
1137/*
1138 * A simpler version of process_responses() that handles only pure (i.e.,
1139 * non data-carrying) responses. Such respones are too light-weight to justify
1140 * calling a softirq when using NAPI, so we handle them specially in hard
1141 * interrupt context. The function is called with a pointer to a response,
1142 * which the caller must ensure is a valid pure response. Returns 1 if it
1143 * encounters a valid data-carrying response, 0 otherwise.
1144 */
1145static int process_pure_responses(struct adapter *adapter, struct respQ_e *e)
1146{
1147 struct sge *sge = adapter->sge;
1148 struct respQ *q = &sge->respQ;
1149 unsigned int flags = 0;
1150 unsigned int cmdq_processed[SGE_CMDQ_N] = {0, 0};
1151
1152 do {
1153 flags |= e->Qsleeping;
1154
1155 cmdq_processed[0] += e->Cmdq0CreditReturn;
1156 cmdq_processed[1] += e->Cmdq1CreditReturn;
1157
1158 e++;
1159 if (unlikely(++q->cidx == q->size)) {
1160 q->cidx = 0;
1161 q->genbit ^= 1;
1162 e = q->entries;
1163 }
1164 prefetch(e);
1165
1166 if (++q->credits > SGE_RESPQ_REPLENISH_THRES) {
1167 writel(q->credits, adapter->regs + A_SG_RSPQUEUECREDIT);
1168 q->credits = 0;
1169 }
1170 sge->stats.pure_rsps++;
1171 } while (e->GenerationBit == q->genbit && !e->DataValid);
1172
1173 flags = update_tx_info(adapter, flags, cmdq_processed[0]);
1174 sge->cmdQ[1].processed += cmdq_processed[1];
1175
1176 return e->GenerationBit == q->genbit;
1177}
1178
1179/*
1180 * Handler for new data events when using NAPI. This does not need any locking
1181 * or protection from interrupts as data interrupts are off at this point and
1182 * other adapter interrupts do not interfere.
1183 */
1184static int t1_poll(struct net_device *dev, int *budget)
1185{
1186 struct adapter *adapter = dev->priv;
1187 int effective_budget = min(*budget, dev->quota);
1188
1189 int work_done = process_responses(adapter, effective_budget);
1190 *budget -= work_done;
1191 dev->quota -= work_done;
1192
1193 if (work_done >= effective_budget)
1194 return 1;
1195
1196 __netif_rx_complete(dev);
1197
1198 /*
1199 * Because we don't atomically flush the following write it is
1200 * possible that in very rare cases it can reach the device in a way
1201 * that races with a new response being written plus an error interrupt
1202 * causing the NAPI interrupt handler below to return unhandled status
1203 * to the OS. To protect against this would require flushing the write
1204 * and doing both the write and the flush with interrupts off. Way too
1205 * expensive and unjustifiable given the rarity of the race.
1206 */
1207 writel(adapter->sge->respQ.cidx, adapter->regs + A_SG_SLEEPING);
1208 return 0;
1209}
1210
1211/*
1212 * Returns true if the device is already scheduled for polling.
1213 */
1214static inline int napi_is_scheduled(struct net_device *dev)
1215{
1216 return test_bit(__LINK_STATE_RX_SCHED, &dev->state);
1217}
1218
1219/*
1220 * NAPI version of the main interrupt handler.
1221 */
1222static irqreturn_t t1_interrupt_napi(int irq, void *data, struct pt_regs *regs)
1223{
1224 int handled;
1225 struct adapter *adapter = data;
1226 struct sge *sge = adapter->sge;
1227 struct respQ *q = &adapter->sge->respQ;
1228
1229 /*
1230 * Clear the SGE_DATA interrupt first thing. Normally the NAPI
1231 * handler has control of the response queue and the interrupt handler
1232 * can look at the queue reliably only once it knows NAPI is off.
1233 * We can't wait that long to clear the SGE_DATA interrupt because we
1234 * could race with t1_poll rearming the SGE interrupt, so we need to
1235 * clear the interrupt speculatively and really early on.
1236 */
1237 writel(F_PL_INTR_SGE_DATA, adapter->regs + A_PL_CAUSE);
1238
1239 spin_lock(&adapter->async_lock);
1240 if (!napi_is_scheduled(sge->netdev)) {
1241 struct respQ_e *e = &q->entries[q->cidx];
1242
1243 if (e->GenerationBit == q->genbit) {
1244 if (e->DataValid ||
1245 process_pure_responses(adapter, e)) {
1246 if (likely(napi_schedule_prep(sge->netdev)))
1247 __netif_rx_schedule(sge->netdev);
1248 else
1249 printk(KERN_CRIT
1250 "NAPI schedule failure!\n");
1251 } else
1252 writel(q->cidx, adapter->regs + A_SG_SLEEPING);
1253 handled = 1;
1254 goto unlock;
1255 } else
1256 writel(q->cidx, adapter->regs + A_SG_SLEEPING);
1257 } else
1258 if (readl(adapter->regs + A_PL_CAUSE) & F_PL_INTR_SGE_DATA)
1259 printk(KERN_ERR "data interrupt while NAPI running\n");
1260
1261 handled = t1_slow_intr_handler(adapter);
1262 if (!handled)
1263 sge->stats.unhandled_irqs++;
1264 unlock:
1265 spin_unlock(&adapter->async_lock);
1266 return IRQ_RETVAL(handled != 0);
1267}
1268
1269/*
1270 * Main interrupt handler, optimized assuming that we took a 'DATA'
1271 * interrupt.
1272 *
1273 * 1. Clear the interrupt
1274 * 2. Loop while we find valid descriptors and process them; accumulate
1275 * information that can be processed after the loop
1276 * 3. Tell the SGE at which index we stopped processing descriptors
1277 * 4. Bookkeeping; free TX buffers, ring doorbell if there are any
1278 * outstanding TX buffers waiting, replenish RX buffers, potentially
1279 * reenable upper layers if they were turned off due to lack of TX
1280 * resources which are available again.
1281 * 5. If we took an interrupt, but no valid respQ descriptors was found we
1282 * let the slow_intr_handler run and do error handling.
1283 */
1284static irqreturn_t t1_interrupt(int irq, void *cookie, struct pt_regs *regs)
1285{
1286 int work_done;
1287 struct respQ_e *e;
1288 struct adapter *adapter = cookie;
1289 struct respQ *Q = &adapter->sge->respQ;
1290
1291 spin_lock(&adapter->async_lock);
1292 e = &Q->entries[Q->cidx];
1293 prefetch(e);
1294
1295 writel(F_PL_INTR_SGE_DATA, adapter->regs + A_PL_CAUSE);
1296
1297 if (likely(e->GenerationBit == Q->genbit))
1298 work_done = process_responses(adapter, -1);
1299 else
1300 work_done = t1_slow_intr_handler(adapter);
1301
1302 /*
1303 * The unconditional clearing of the PL_CAUSE above may have raced
1304 * with DMA completion and the corresponding generation of a response
1305 * to cause us to miss the resulting data interrupt. The next write
1306 * is also unconditional to recover the missed interrupt and render
1307 * this race harmless.
1308 */
1309 writel(Q->cidx, adapter->regs + A_SG_SLEEPING);
1310
1311 if (!work_done)
1312 adapter->sge->stats.unhandled_irqs++;
1313 spin_unlock(&adapter->async_lock);
1314 return IRQ_RETVAL(work_done != 0);
1315}
1316
1317intr_handler_t t1_select_intr_handler(adapter_t *adapter)
1318{
1319 return adapter->params.sge.polling ? t1_interrupt_napi : t1_interrupt;
1320}
1321
1322/*
1323 * Enqueues the sk_buff onto the cmdQ[qid] and has hardware fetch it.
1324 *
1325 * The code figures out how many entries the sk_buff will require in the
1326 * cmdQ and updates the cmdQ data structure with the state once the enqueue
1327 * has complete. Then, it doesn't access the global structure anymore, but
1328 * uses the corresponding fields on the stack. In conjuction with a spinlock
1329 * around that code, we can make the function reentrant without holding the
1330 * lock when we actually enqueue (which might be expensive, especially on
1331 * architectures with IO MMUs).
1332 *
1333 * This runs with softirqs disabled.
1334 */
1335unsigned int t1_sge_tx(struct sk_buff *skb, struct adapter *adapter,
1336 unsigned int qid, struct net_device *dev)
1337{
1338 struct sge *sge = adapter->sge;
1339 struct cmdQ *q = &sge->cmdQ[qid];
1340 unsigned int credits, pidx, genbit, count;
1341
1342 spin_lock(&q->lock);
1343 reclaim_completed_tx(sge, q);
1344
1345 pidx = q->pidx;
1346 credits = q->size - q->in_use;
1347 count = 1 + skb_shinfo(skb)->nr_frags;
1348
1349 { /* Ethernet packet */
1350 if (unlikely(credits < count)) {
1351 netif_stop_queue(dev);
1352 set_bit(dev->if_port, &sge->stopped_tx_queues);
1353 sge->stats.cmdQ_full[3]++;
1354 spin_unlock(&q->lock);
1355 CH_ERR("%s: Tx ring full while queue awake!\n",
1356 adapter->name);
1357 return 1;
1358 }
1359 if (unlikely(credits - count < q->stop_thres)) {
1360 sge->stats.cmdQ_full[3]++;
1361 netif_stop_queue(dev);
1362 set_bit(dev->if_port, &sge->stopped_tx_queues);
1363 }
1364 }
1365 q->in_use += count;
1366 genbit = q->genbit;
1367 q->pidx += count;
1368 if (q->pidx >= q->size) {
1369 q->pidx -= q->size;
1370 q->genbit ^= 1;
1371 }
1372 spin_unlock(&q->lock);
1373
1374 write_tx_descs(adapter, skb, pidx, genbit, q);
1375
1376 /*
1377 * We always ring the doorbell for cmdQ1. For cmdQ0, we only ring
1378 * the doorbell if the Q is asleep. There is a natural race, where
1379 * the hardware is going to sleep just after we checked, however,
1380 * then the interrupt handler will detect the outstanding TX packet
1381 * and ring the doorbell for us.
1382 */
1383 if (qid)
1384 doorbell_pio(adapter, F_CMDQ1_ENABLE);
1385 else {
1386 clear_bit(CMDQ_STAT_LAST_PKT_DB, &q->status);
1387 if (test_and_set_bit(CMDQ_STAT_RUNNING, &q->status) == 0) {
1388 set_bit(CMDQ_STAT_LAST_PKT_DB, &q->status);
1389 writel(F_CMDQ0_ENABLE, adapter->regs + A_SG_DOORBELL);
1390 }
1391 }
1392 return 0;
1393}
1394
1395#define MK_ETH_TYPE_MSS(type, mss) (((mss) & 0x3FFF) | ((type) << 14))
1396
1397/*
1398 * eth_hdr_len - return the length of an Ethernet header
1399 * @data: pointer to the start of the Ethernet header
1400 *
1401 * Returns the length of an Ethernet header, including optional VLAN tag.
1402 */
1403static inline int eth_hdr_len(const void *data)
1404{
1405 const struct ethhdr *e = data;
1406
1407 return e->h_proto == htons(ETH_P_8021Q) ? VLAN_ETH_HLEN : ETH_HLEN;
1408}
1409
1410/*
1411 * Adds the CPL header to the sk_buff and passes it to t1_sge_tx.
1412 */
1413int t1_start_xmit(struct sk_buff *skb, struct net_device *dev)
1414{
1415 struct adapter *adapter = dev->priv;
1416 struct sge_port_stats *st = &adapter->sge->port_stats[dev->if_port];
1417 struct sge *sge = adapter->sge;
1418 struct cpl_tx_pkt *cpl;
1419
1420#ifdef NETIF_F_TSO
1421 if (skb_shinfo(skb)->tso_size) {
1422 int eth_type;
1423 struct cpl_tx_pkt_lso *hdr;
1424
1425 st->tso++;
1426
1427 eth_type = skb->nh.raw - skb->data == ETH_HLEN ?
1428 CPL_ETH_II : CPL_ETH_II_VLAN;
1429
1430 hdr = (struct cpl_tx_pkt_lso *)skb_push(skb, sizeof(*hdr));
1431 hdr->opcode = CPL_TX_PKT_LSO;
1432 hdr->ip_csum_dis = hdr->l4_csum_dis = 0;
1433 hdr->ip_hdr_words = skb->nh.iph->ihl;
1434 hdr->tcp_hdr_words = skb->h.th->doff;
1435 hdr->eth_type_mss = htons(MK_ETH_TYPE_MSS(eth_type,
1436 skb_shinfo(skb)->tso_size));
1437 hdr->len = htonl(skb->len - sizeof(*hdr));
1438 cpl = (struct cpl_tx_pkt *)hdr;
1439 sge->stats.tx_lso_pkts++;
1440 } else
1441#endif
1442 {
1443 /*
1444 * Packets shorter than ETH_HLEN can break the MAC, drop them
1445 * early. Also, we may get oversized packets because some
1446 * parts of the kernel don't handle our unusual hard_header_len
1447 * right, drop those too.
1448 */
1449 if (unlikely(skb->len < ETH_HLEN ||
1450 skb->len > dev->mtu + eth_hdr_len(skb->data))) {
1451 dev_kfree_skb_any(skb);
1452 return NET_XMIT_SUCCESS;
1453 }
1454
1455 /*
1456 * We are using a non-standard hard_header_len and some kernel
1457 * components, such as pktgen, do not handle it right.
1458 * Complain when this happens but try to fix things up.
1459 */
1460 if (unlikely(skb_headroom(skb) <
1461 dev->hard_header_len - ETH_HLEN)) {
1462 struct sk_buff *orig_skb = skb;
1463
1464 if (net_ratelimit())
1465 printk(KERN_ERR "%s: inadequate headroom in "
1466 "Tx packet\n", dev->name);
1467 skb = skb_realloc_headroom(skb, sizeof(*cpl));
1468 dev_kfree_skb_any(orig_skb);
1469 if (!skb)
1470 return -ENOMEM;
1471 }
1472
1473 if (!(adapter->flags & UDP_CSUM_CAPABLE) &&
1474 skb->ip_summed == CHECKSUM_HW &&
1475 skb->nh.iph->protocol == IPPROTO_UDP)
1476 if (unlikely(skb_checksum_help(skb, 0))) {
1477 dev_kfree_skb_any(skb);
1478 return -ENOMEM;
1479 }
1480
1481 /* Hmmm, assuming to catch the gratious arp... and we'll use
1482 * it to flush out stuck espi packets...
1483 */
1484 if (unlikely(!adapter->sge->espibug_skb)) {
1485 if (skb->protocol == htons(ETH_P_ARP) &&
1486 skb->nh.arph->ar_op == htons(ARPOP_REQUEST)) {
1487 adapter->sge->espibug_skb = skb;
1488 /* We want to re-use this skb later. We
1489 * simply bump the reference count and it
1490 * will not be freed...
1491 */
1492 skb = skb_get(skb);
1493 }
1494 }
1495
1496 cpl = (struct cpl_tx_pkt *)__skb_push(skb, sizeof(*cpl));
1497 cpl->opcode = CPL_TX_PKT;
1498 cpl->ip_csum_dis = 1; /* SW calculates IP csum */
1499 cpl->l4_csum_dis = skb->ip_summed == CHECKSUM_HW ? 0 : 1;
1500 /* the length field isn't used so don't bother setting it */
1501
1502 st->tx_cso += (skb->ip_summed == CHECKSUM_HW);
1503 sge->stats.tx_do_cksum += (skb->ip_summed == CHECKSUM_HW);
1504 sge->stats.tx_reg_pkts++;
1505 }
1506 cpl->iff = dev->if_port;
1507
1508#if defined(CONFIG_VLAN_8021Q) || defined(CONFIG_VLAN_8021Q_MODULE)
1509 if (adapter->vlan_grp && vlan_tx_tag_present(skb)) {
1510 cpl->vlan_valid = 1;
1511 cpl->vlan = htons(vlan_tx_tag_get(skb));
1512 st->vlan_insert++;
1513 } else
1514#endif
1515 cpl->vlan_valid = 0;
1516
1517 dev->trans_start = jiffies;
1518 return t1_sge_tx(skb, adapter, 0, dev);
1519}
1520
1521/*
1522 * Callback for the Tx buffer reclaim timer. Runs with softirqs disabled.
1523 */
1524static void sge_tx_reclaim_cb(unsigned long data)
1525{
1526 int i;
1527 struct sge *sge = (struct sge *)data;
1528
1529 for (i = 0; i < SGE_CMDQ_N; ++i) {
1530 struct cmdQ *q = &sge->cmdQ[i];
1531
1532 if (!spin_trylock(&q->lock))
1533 continue;
1534
1535 reclaim_completed_tx(sge, q);
1536 if (i == 0 && q->in_use) /* flush pending credits */
1537 writel(F_CMDQ0_ENABLE,
1538 sge->adapter->regs + A_SG_DOORBELL);
1539
1540 spin_unlock(&q->lock);
1541 }
1542 mod_timer(&sge->tx_reclaim_timer, jiffies + TX_RECLAIM_PERIOD);
1543}
1544
1545/*
1546 * Propagate changes of the SGE coalescing parameters to the HW.
1547 */
1548int t1_sge_set_coalesce_params(struct sge *sge, struct sge_params *p)
1549{
1550 sge->netdev->poll = t1_poll;
1551 sge->fixed_intrtimer = p->rx_coalesce_usecs *
1552 core_ticks_per_usec(sge->adapter);
1553 writel(sge->fixed_intrtimer, sge->adapter->regs + A_SG_INTRTIMER);
1554 return 0;
1555}
1556
1557/*
1558 * Allocates both RX and TX resources and configures the SGE. However,
1559 * the hardware is not enabled yet.
1560 */
1561int t1_sge_configure(struct sge *sge, struct sge_params *p)
1562{
1563 if (alloc_rx_resources(sge, p))
1564 return -ENOMEM;
1565 if (alloc_tx_resources(sge, p)) {
1566 free_rx_resources(sge);
1567 return -ENOMEM;
1568 }
1569 configure_sge(sge, p);
1570
1571 /*
1572 * Now that we have sized the free lists calculate the payload
1573 * capacity of the large buffers. Other parts of the driver use
1574 * this to set the max offload coalescing size so that RX packets
1575 * do not overflow our large buffers.
1576 */
1577 p->large_buf_capacity = jumbo_payload_capacity(sge);
1578 return 0;
1579}
1580
1581/*
1582 * Disables the DMA engine.
1583 */
1584void t1_sge_stop(struct sge *sge)
1585{
1586 writel(0, sge->adapter->regs + A_SG_CONTROL);
1587 (void) readl(sge->adapter->regs + A_SG_CONTROL); /* flush */
1588 if (is_T2(sge->adapter))
1589 del_timer_sync(&sge->espibug_timer);
1590 del_timer_sync(&sge->tx_reclaim_timer);
1591}
1592
1593/*
1594 * Enables the DMA engine.
1595 */
1596void t1_sge_start(struct sge *sge)
1597{
1598 refill_free_list(sge, &sge->freelQ[0]);
1599 refill_free_list(sge, &sge->freelQ[1]);
1600
1601 writel(sge->sge_control, sge->adapter->regs + A_SG_CONTROL);
1602 doorbell_pio(sge->adapter, F_FL0_ENABLE | F_FL1_ENABLE);
1603 (void) readl(sge->adapter->regs + A_SG_CONTROL); /* flush */
1604
1605 mod_timer(&sge->tx_reclaim_timer, jiffies + TX_RECLAIM_PERIOD);
1606
1607 if (is_T2(sge->adapter))
1608 mod_timer(&sge->espibug_timer, jiffies + sge->espibug_timeout);
1609}
1610
1611/*
1612 * Callback for the T2 ESPI 'stuck packet feature' workaorund
1613 */
1614static void espibug_workaround(void *data)
1615{
1616 struct adapter *adapter = (struct adapter *)data;
1617 struct sge *sge = adapter->sge;
1618
1619 if (netif_running(adapter->port[0].dev)) {
1620 struct sk_buff *skb = sge->espibug_skb;
1621
1622 u32 seop = t1_espi_get_mon(adapter, 0x930, 0);
1623
1624 if ((seop & 0xfff0fff) == 0xfff && skb) {
1625 if (!skb->cb[0]) {
1626 u8 ch_mac_addr[ETH_ALEN] =
1627 {0x0, 0x7, 0x43, 0x0, 0x0, 0x0};
1628 memcpy(skb->data + sizeof(struct cpl_tx_pkt),
1629 ch_mac_addr, ETH_ALEN);
1630 memcpy(skb->data + skb->len - 10, ch_mac_addr,
1631 ETH_ALEN);
1632 skb->cb[0] = 0xff;
1633 }
1634
1635 /* bump the reference count to avoid freeing of the
1636 * skb once the DMA has completed.
1637 */
1638 skb = skb_get(skb);
1639 t1_sge_tx(skb, adapter, 0, adapter->port[0].dev);
1640 }
1641 }
1642 mod_timer(&sge->espibug_timer, jiffies + sge->espibug_timeout);
1643}
1644
1645/*
1646 * Creates a t1_sge structure and returns suggested resource parameters.
1647 */
1648struct sge * __devinit t1_sge_create(struct adapter *adapter,
1649 struct sge_params *p)
1650{
1651 struct sge *sge = kmalloc(sizeof(*sge), GFP_KERNEL);
1652
1653 if (!sge)
1654 return NULL;
1655 memset(sge, 0, sizeof(*sge));
1656
1657 sge->adapter = adapter;
1658 sge->netdev = adapter->port[0].dev;
1659 sge->rx_pkt_pad = t1_is_T1B(adapter) ? 0 : 2;
1660 sge->jumbo_fl = t1_is_T1B(adapter) ? 1 : 0;
1661
1662 init_timer(&sge->tx_reclaim_timer);
1663 sge->tx_reclaim_timer.data = (unsigned long)sge;
1664 sge->tx_reclaim_timer.function = sge_tx_reclaim_cb;
1665
1666 if (is_T2(sge->adapter)) {
1667 init_timer(&sge->espibug_timer);
1668 sge->espibug_timer.function = (void *)&espibug_workaround;
1669 sge->espibug_timer.data = (unsigned long)sge->adapter;
1670 sge->espibug_timeout = 1;
1671 }
1672
1673
1674 p->cmdQ_size[0] = SGE_CMDQ0_E_N;
1675 p->cmdQ_size[1] = SGE_CMDQ1_E_N;
1676 p->freelQ_size[!sge->jumbo_fl] = SGE_FREEL_SIZE;
1677 p->freelQ_size[sge->jumbo_fl] = SGE_JUMBO_FREEL_SIZE;
1678 p->rx_coalesce_usecs = 50;
1679 p->coalesce_enable = 0;
1680 p->sample_interval_usecs = 0;
1681 p->polling = 0;
1682
1683 return sge;
1684}
diff --git a/drivers/net/chelsio/sge.h b/drivers/net/chelsio/sge.h
new file mode 100644
index 000000000000..434b25586851
--- /dev/null
+++ b/drivers/net/chelsio/sge.h
@@ -0,0 +1,105 @@
1/*****************************************************************************
2 * *
3 * File: sge.h *
4 * $Revision: 1.11 $ *
5 * $Date: 2005/06/21 22:10:55 $ *
6 * Description: *
7 * part of the Chelsio 10Gb Ethernet Driver. *
8 * *
9 * This program is free software; you can redistribute it and/or modify *
10 * it under the terms of the GNU General Public License, version 2, as *
11 * published by the Free Software Foundation. *
12 * *
13 * You should have received a copy of the GNU General Public License along *
14 * with this program; if not, write to the Free Software Foundation, Inc., *
15 * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
16 * *
17 * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED *
18 * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF *
19 * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. *
20 * *
21 * http://www.chelsio.com *
22 * *
23 * Copyright (c) 2003 - 2005 Chelsio Communications, Inc. *
24 * All rights reserved. *
25 * *
26 * Maintainers: maintainers@chelsio.com *
27 * *
28 * Authors: Dimitrios Michailidis <dm@chelsio.com> *
29 * Tina Yang <tainay@chelsio.com> *
30 * Felix Marti <felix@chelsio.com> *
31 * Scott Bardone <sbardone@chelsio.com> *
32 * Kurt Ottaway <kottaway@chelsio.com> *
33 * Frank DiMambro <frank@chelsio.com> *
34 * *
35 * History: *
36 * *
37 ****************************************************************************/
38
39#ifndef _CXGB_SGE_H_
40#define _CXGB_SGE_H_
41
42#include <linux/types.h>
43#include <linux/interrupt.h>
44#include <asm/byteorder.h>
45
46#ifndef IRQ_RETVAL
47#define IRQ_RETVAL(x)
48typedef void irqreturn_t;
49#endif
50
51typedef irqreturn_t (*intr_handler_t)(int, void *, struct pt_regs *);
52
53struct sge_intr_counts {
54 unsigned int respQ_empty; /* # times respQ empty */
55 unsigned int respQ_overflow; /* # respQ overflow (fatal) */
56 unsigned int freelistQ_empty; /* # times freelist empty */
57 unsigned int pkt_too_big; /* packet too large (fatal) */
58 unsigned int pkt_mismatch;
59 unsigned int cmdQ_full[3]; /* not HW IRQ, host cmdQ[] full */
60 unsigned int cmdQ_restarted[3];/* # of times cmdQ X was restarted */
61 unsigned int ethernet_pkts; /* # of Ethernet packets received */
62 unsigned int offload_pkts; /* # of offload packets received */
63 unsigned int offload_bundles; /* # of offload pkt bundles delivered */
64 unsigned int pure_rsps; /* # of non-payload responses */
65 unsigned int unhandled_irqs; /* # of unhandled interrupts */
66 unsigned int tx_ipfrags;
67 unsigned int tx_reg_pkts;
68 unsigned int tx_lso_pkts;
69 unsigned int tx_do_cksum;
70};
71
72struct sge_port_stats {
73 unsigned long rx_cso_good; /* # of successful RX csum offloads */
74 unsigned long tx_cso; /* # of TX checksum offloads */
75 unsigned long vlan_xtract; /* # of VLAN tag extractions */
76 unsigned long vlan_insert; /* # of VLAN tag extractions */
77 unsigned long tso; /* # of TSO requests */
78 unsigned long rx_drops; /* # of packets dropped due to no mem */
79};
80
81struct sk_buff;
82struct net_device;
83struct adapter;
84struct sge_params;
85struct sge;
86
87struct sge *t1_sge_create(struct adapter *, struct sge_params *);
88int t1_sge_configure(struct sge *, struct sge_params *);
89int t1_sge_set_coalesce_params(struct sge *, struct sge_params *);
90void t1_sge_destroy(struct sge *);
91intr_handler_t t1_select_intr_handler(adapter_t *adapter);
92unsigned int t1_sge_tx(struct sk_buff *skb, struct adapter *adapter,
93 unsigned int qid, struct net_device *netdev);
94int t1_start_xmit(struct sk_buff *skb, struct net_device *dev);
95void t1_set_vlan_accel(struct adapter *adapter, int on_off);
96void t1_sge_start(struct sge *);
97void t1_sge_stop(struct sge *);
98int t1_sge_intr_error_handler(struct sge *);
99void t1_sge_intr_enable(struct sge *);
100void t1_sge_intr_disable(struct sge *);
101void t1_sge_intr_clear(struct sge *);
102const struct sge_intr_counts *t1_sge_get_intr_counts(struct sge *sge);
103const struct sge_port_stats *t1_sge_get_port_stats(struct sge *sge, int port);
104
105#endif /* _CXGB_SGE_H_ */
diff --git a/drivers/net/chelsio/subr.c b/drivers/net/chelsio/subr.c
new file mode 100644
index 000000000000..1ebb5d149aef
--- /dev/null
+++ b/drivers/net/chelsio/subr.c
@@ -0,0 +1,812 @@
1/*****************************************************************************
2 * *
3 * File: subr.c *
4 * $Revision: 1.27 $ *
5 * $Date: 2005/06/22 01:08:36 $ *
6 * Description: *
7 * Various subroutines (intr,pio,etc.) used by Chelsio 10G Ethernet driver. *
8 * part of the Chelsio 10Gb Ethernet Driver. *
9 * *
10 * This program is free software; you can redistribute it and/or modify *
11 * it under the terms of the GNU General Public License, version 2, as *
12 * published by the Free Software Foundation. *
13 * *
14 * You should have received a copy of the GNU General Public License along *
15 * with this program; if not, write to the Free Software Foundation, Inc., *
16 * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
17 * *
18 * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED *
19 * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF *
20 * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. *
21 * *
22 * http://www.chelsio.com *
23 * *
24 * Copyright (c) 2003 - 2005 Chelsio Communications, Inc. *
25 * All rights reserved. *
26 * *
27 * Maintainers: maintainers@chelsio.com *
28 * *
29 * Authors: Dimitrios Michailidis <dm@chelsio.com> *
30 * Tina Yang <tainay@chelsio.com> *
31 * Felix Marti <felix@chelsio.com> *
32 * Scott Bardone <sbardone@chelsio.com> *
33 * Kurt Ottaway <kottaway@chelsio.com> *
34 * Frank DiMambro <frank@chelsio.com> *
35 * *
36 * History: *
37 * *
38 ****************************************************************************/
39
40#include "common.h"
41#include "elmer0.h"
42#include "regs.h"
43#include "gmac.h"
44#include "cphy.h"
45#include "sge.h"
46#include "espi.h"
47
48/**
49 * t1_wait_op_done - wait until an operation is completed
50 * @adapter: the adapter performing the operation
51 * @reg: the register to check for completion
52 * @mask: a single-bit field within @reg that indicates completion
53 * @polarity: the value of the field when the operation is completed
54 * @attempts: number of check iterations
55 * @delay: delay in usecs between iterations
56 *
57 * Wait until an operation is completed by checking a bit in a register
58 * up to @attempts times. Returns %0 if the operation completes and %1
59 * otherwise.
60 */
61static int t1_wait_op_done(adapter_t *adapter, int reg, u32 mask, int polarity,
62 int attempts, int delay)
63{
64 while (1) {
65 u32 val = readl(adapter->regs + reg) & mask;
66
67 if (!!val == polarity)
68 return 0;
69 if (--attempts == 0)
70 return 1;
71 if (delay)
72 udelay(delay);
73 }
74}
75
76#define TPI_ATTEMPTS 50
77
78/*
79 * Write a register over the TPI interface (unlocked and locked versions).
80 */
81static int __t1_tpi_write(adapter_t *adapter, u32 addr, u32 value)
82{
83 int tpi_busy;
84
85 writel(addr, adapter->regs + A_TPI_ADDR);
86 writel(value, adapter->regs + A_TPI_WR_DATA);
87 writel(F_TPIWR, adapter->regs + A_TPI_CSR);
88
89 tpi_busy = t1_wait_op_done(adapter, A_TPI_CSR, F_TPIRDY, 1,
90 TPI_ATTEMPTS, 3);
91 if (tpi_busy)
92 CH_ALERT("%s: TPI write to 0x%x failed\n",
93 adapter->name, addr);
94 return tpi_busy;
95}
96
97int t1_tpi_write(adapter_t *adapter, u32 addr, u32 value)
98{
99 int ret;
100
101 spin_lock(&(adapter)->tpi_lock);
102 ret = __t1_tpi_write(adapter, addr, value);
103 spin_unlock(&(adapter)->tpi_lock);
104 return ret;
105}
106
107/*
108 * Read a register over the TPI interface (unlocked and locked versions).
109 */
110static int __t1_tpi_read(adapter_t *adapter, u32 addr, u32 *valp)
111{
112 int tpi_busy;
113
114 writel(addr, adapter->regs + A_TPI_ADDR);
115 writel(0, adapter->regs + A_TPI_CSR);
116
117 tpi_busy = t1_wait_op_done(adapter, A_TPI_CSR, F_TPIRDY, 1,
118 TPI_ATTEMPTS, 3);
119 if (tpi_busy)
120 CH_ALERT("%s: TPI read from 0x%x failed\n",
121 adapter->name, addr);
122 else
123 *valp = readl(adapter->regs + A_TPI_RD_DATA);
124 return tpi_busy;
125}
126
127int t1_tpi_read(adapter_t *adapter, u32 addr, u32 *valp)
128{
129 int ret;
130
131 spin_lock(&(adapter)->tpi_lock);
132 ret = __t1_tpi_read(adapter, addr, valp);
133 spin_unlock(&(adapter)->tpi_lock);
134 return ret;
135}
136
137/*
138 * Called when a port's link settings change to propagate the new values to the
139 * associated PHY and MAC. After performing the common tasks it invokes an
140 * OS-specific handler.
141 */
142/* static */ void link_changed(adapter_t *adapter, int port_id)
143{
144 int link_ok, speed, duplex, fc;
145 struct cphy *phy = adapter->port[port_id].phy;
146 struct link_config *lc = &adapter->port[port_id].link_config;
147
148 phy->ops->get_link_status(phy, &link_ok, &speed, &duplex, &fc);
149
150 lc->speed = speed < 0 ? SPEED_INVALID : speed;
151 lc->duplex = duplex < 0 ? DUPLEX_INVALID : duplex;
152 if (!(lc->requested_fc & PAUSE_AUTONEG))
153 fc = lc->requested_fc & (PAUSE_RX | PAUSE_TX);
154
155 if (link_ok && speed >= 0 && lc->autoneg == AUTONEG_ENABLE) {
156 /* Set MAC speed, duplex, and flow control to match PHY. */
157 struct cmac *mac = adapter->port[port_id].mac;
158
159 mac->ops->set_speed_duplex_fc(mac, speed, duplex, fc);
160 lc->fc = (unsigned char)fc;
161 }
162 t1_link_changed(adapter, port_id, link_ok, speed, duplex, fc);
163}
164
165static int t1_pci_intr_handler(adapter_t *adapter)
166{
167 u32 pcix_cause;
168
169 pci_read_config_dword(adapter->pdev, A_PCICFG_INTR_CAUSE, &pcix_cause);
170
171 if (pcix_cause) {
172 pci_write_config_dword(adapter->pdev, A_PCICFG_INTR_CAUSE,
173 pcix_cause);
174 t1_fatal_err(adapter); /* PCI errors are fatal */
175 }
176 return 0;
177}
178
179
180/*
181 * Wait until Elmer's MI1 interface is ready for new operations.
182 */
183static int mi1_wait_until_ready(adapter_t *adapter, int mi1_reg)
184{
185 int attempts = 100, busy;
186
187 do {
188 u32 val;
189
190 __t1_tpi_read(adapter, mi1_reg, &val);
191 busy = val & F_MI1_OP_BUSY;
192 if (busy)
193 udelay(10);
194 } while (busy && --attempts);
195 if (busy)
196 CH_ALERT("%s: MDIO operation timed out\n",
197 adapter->name);
198 return busy;
199}
200
201/*
202 * MI1 MDIO initialization.
203 */
204static void mi1_mdio_init(adapter_t *adapter, const struct board_info *bi)
205{
206 u32 clkdiv = bi->clock_elmer0 / (2 * bi->mdio_mdc) - 1;
207 u32 val = F_MI1_PREAMBLE_ENABLE | V_MI1_MDI_INVERT(bi->mdio_mdiinv) |
208 V_MI1_MDI_ENABLE(bi->mdio_mdien) | V_MI1_CLK_DIV(clkdiv);
209
210 if (!(bi->caps & SUPPORTED_10000baseT_Full))
211 val |= V_MI1_SOF(1);
212 t1_tpi_write(adapter, A_ELMER0_PORT0_MI1_CFG, val);
213}
214
215static int mi1_mdio_ext_read(adapter_t *adapter, int phy_addr, int mmd_addr,
216 int reg_addr, unsigned int *valp)
217{
218 u32 addr = V_MI1_REG_ADDR(mmd_addr) | V_MI1_PHY_ADDR(phy_addr);
219
220 spin_lock(&(adapter)->tpi_lock);
221
222 /* Write the address we want. */
223 __t1_tpi_write(adapter, A_ELMER0_PORT0_MI1_ADDR, addr);
224 __t1_tpi_write(adapter, A_ELMER0_PORT0_MI1_DATA, reg_addr);
225 __t1_tpi_write(adapter, A_ELMER0_PORT0_MI1_OP,
226 MI1_OP_INDIRECT_ADDRESS);
227 mi1_wait_until_ready(adapter, A_ELMER0_PORT0_MI1_OP);
228
229 /* Write the operation we want. */
230 __t1_tpi_write(adapter, A_ELMER0_PORT0_MI1_OP, MI1_OP_INDIRECT_READ);
231 mi1_wait_until_ready(adapter, A_ELMER0_PORT0_MI1_OP);
232
233 /* Read the data. */
234 __t1_tpi_read(adapter, A_ELMER0_PORT0_MI1_DATA, valp);
235 spin_unlock(&(adapter)->tpi_lock);
236 return 0;
237}
238
239static int mi1_mdio_ext_write(adapter_t *adapter, int phy_addr, int mmd_addr,
240 int reg_addr, unsigned int val)
241{
242 u32 addr = V_MI1_REG_ADDR(mmd_addr) | V_MI1_PHY_ADDR(phy_addr);
243
244 spin_lock(&(adapter)->tpi_lock);
245
246 /* Write the address we want. */
247 __t1_tpi_write(adapter, A_ELMER0_PORT0_MI1_ADDR, addr);
248 __t1_tpi_write(adapter, A_ELMER0_PORT0_MI1_DATA, reg_addr);
249 __t1_tpi_write(adapter, A_ELMER0_PORT0_MI1_OP,
250 MI1_OP_INDIRECT_ADDRESS);
251 mi1_wait_until_ready(adapter, A_ELMER0_PORT0_MI1_OP);
252
253 /* Write the data. */
254 __t1_tpi_write(adapter, A_ELMER0_PORT0_MI1_DATA, val);
255 __t1_tpi_write(adapter, A_ELMER0_PORT0_MI1_OP, MI1_OP_INDIRECT_WRITE);
256 mi1_wait_until_ready(adapter, A_ELMER0_PORT0_MI1_OP);
257 spin_unlock(&(adapter)->tpi_lock);
258 return 0;
259}
260
261static struct mdio_ops mi1_mdio_ext_ops = {
262 mi1_mdio_init,
263 mi1_mdio_ext_read,
264 mi1_mdio_ext_write
265};
266
267enum {
268 CH_BRD_N110_1F,
269 CH_BRD_N210_1F,
270};
271
272static struct board_info t1_board[] = {
273
274{ CHBT_BOARD_N110, 1/*ports#*/,
275 SUPPORTED_10000baseT_Full | SUPPORTED_FIBRE /*caps*/, CHBT_TERM_T1,
276 CHBT_MAC_PM3393, CHBT_PHY_88X2010,
277 125000000/*clk-core*/, 0/*clk-mc3*/, 0/*clk-mc4*/,
278 1/*espi-ports*/, 0/*clk-cspi*/, 44/*clk-elmer0*/, 0/*mdien*/,
279 0/*mdiinv*/, 1/*mdc*/, 0/*phybaseaddr*/, &t1_pm3393_ops,
280 &t1_mv88x201x_ops, &mi1_mdio_ext_ops,
281 "Chelsio N110 1x10GBaseX NIC" },
282
283{ CHBT_BOARD_N210, 1/*ports#*/,
284 SUPPORTED_10000baseT_Full | SUPPORTED_FIBRE /*caps*/, CHBT_TERM_T2,
285 CHBT_MAC_PM3393, CHBT_PHY_88X2010,
286 125000000/*clk-core*/, 0/*clk-mc3*/, 0/*clk-mc4*/,
287 1/*espi-ports*/, 0/*clk-cspi*/, 44/*clk-elmer0*/, 0/*mdien*/,
288 0/*mdiinv*/, 1/*mdc*/, 0/*phybaseaddr*/, &t1_pm3393_ops,
289 &t1_mv88x201x_ops, &mi1_mdio_ext_ops,
290 "Chelsio N210 1x10GBaseX NIC" },
291
292};
293
294struct pci_device_id t1_pci_tbl[] = {
295 CH_DEVICE(7, 0, CH_BRD_N110_1F),
296 CH_DEVICE(10, 1, CH_BRD_N210_1F),
297 { 0, }
298};
299
300MODULE_DEVICE_TABLE(pci, t1_pci_tbl);
301
302/*
303 * Return the board_info structure with a given index. Out-of-range indices
304 * return NULL.
305 */
306const struct board_info *t1_get_board_info(unsigned int board_id)
307{
308 return board_id < ARRAY_SIZE(t1_board) ? &t1_board[board_id] : NULL;
309}
310
311struct chelsio_vpd_t {
312 u32 format_version;
313 u8 serial_number[16];
314 u8 mac_base_address[6];
315 u8 pad[2]; /* make multiple-of-4 size requirement explicit */
316};
317
318#define EEPROMSIZE (8 * 1024)
319#define EEPROM_MAX_POLL 4
320
321/*
322 * Read SEEPROM. A zero is written to the flag register when the addres is
323 * written to the Control register. The hardware device will set the flag to a
324 * one when 4B have been transferred to the Data register.
325 */
326int t1_seeprom_read(adapter_t *adapter, u32 addr, u32 *data)
327{
328 int i = EEPROM_MAX_POLL;
329 u16 val;
330
331 if (addr >= EEPROMSIZE || (addr & 3))
332 return -EINVAL;
333
334 pci_write_config_word(adapter->pdev, A_PCICFG_VPD_ADDR, (u16)addr);
335 do {
336 udelay(50);
337 pci_read_config_word(adapter->pdev, A_PCICFG_VPD_ADDR, &val);
338 } while (!(val & F_VPD_OP_FLAG) && --i);
339
340 if (!(val & F_VPD_OP_FLAG)) {
341 CH_ERR("%s: reading EEPROM address 0x%x failed\n",
342 adapter->name, addr);
343 return -EIO;
344 }
345 pci_read_config_dword(adapter->pdev, A_PCICFG_VPD_DATA, data);
346 *data = le32_to_cpu(*data);
347 return 0;
348}
349
350static int t1_eeprom_vpd_get(adapter_t *adapter, struct chelsio_vpd_t *vpd)
351{
352 int addr, ret = 0;
353
354 for (addr = 0; !ret && addr < sizeof(*vpd); addr += sizeof(u32))
355 ret = t1_seeprom_read(adapter, addr,
356 (u32 *)((u8 *)vpd + addr));
357
358 return ret;
359}
360
361/*
362 * Read a port's MAC address from the VPD ROM.
363 */
364static int vpd_macaddress_get(adapter_t *adapter, int index, u8 mac_addr[])
365{
366 struct chelsio_vpd_t vpd;
367
368 if (t1_eeprom_vpd_get(adapter, &vpd))
369 return 1;
370 memcpy(mac_addr, vpd.mac_base_address, 5);
371 mac_addr[5] = vpd.mac_base_address[5] + index;
372 return 0;
373}
374
375/*
376 * Set up the MAC/PHY according to the requested link settings.
377 *
378 * If the PHY can auto-negotiate first decide what to advertise, then
379 * enable/disable auto-negotiation as desired and reset.
380 *
381 * If the PHY does not auto-negotiate we just reset it.
382 *
383 * If auto-negotiation is off set the MAC to the proper speed/duplex/FC,
384 * otherwise do it later based on the outcome of auto-negotiation.
385 */
386int t1_link_start(struct cphy *phy, struct cmac *mac, struct link_config *lc)
387{
388 unsigned int fc = lc->requested_fc & (PAUSE_RX | PAUSE_TX);
389
390 if (lc->supported & SUPPORTED_Autoneg) {
391 lc->advertising &= ~(ADVERTISED_ASYM_PAUSE | ADVERTISED_PAUSE);
392 if (fc) {
393 lc->advertising |= ADVERTISED_ASYM_PAUSE;
394 if (fc == (PAUSE_RX | PAUSE_TX))
395 lc->advertising |= ADVERTISED_PAUSE;
396 }
397 phy->ops->advertise(phy, lc->advertising);
398
399 if (lc->autoneg == AUTONEG_DISABLE) {
400 lc->speed = lc->requested_speed;
401 lc->duplex = lc->requested_duplex;
402 lc->fc = (unsigned char)fc;
403 mac->ops->set_speed_duplex_fc(mac, lc->speed,
404 lc->duplex, fc);
405 /* Also disables autoneg */
406 phy->ops->set_speed_duplex(phy, lc->speed, lc->duplex);
407 phy->ops->reset(phy, 0);
408 } else
409 phy->ops->autoneg_enable(phy); /* also resets PHY */
410 } else {
411 mac->ops->set_speed_duplex_fc(mac, -1, -1, fc);
412 lc->fc = (unsigned char)fc;
413 phy->ops->reset(phy, 0);
414 }
415 return 0;
416}
417
418/*
419 * External interrupt handler for boards using elmer0.
420 */
421int elmer0_ext_intr_handler(adapter_t *adapter)
422{
423 struct cphy *phy;
424 int phy_cause;
425 u32 cause;
426
427 t1_tpi_read(adapter, A_ELMER0_INT_CAUSE, &cause);
428
429 switch (board_info(adapter)->board) {
430 case CHBT_BOARD_N210:
431 case CHBT_BOARD_N110:
432 if (cause & ELMER0_GP_BIT6) { /* Marvell 88x2010 interrupt */
433 phy = adapter->port[0].phy;
434 phy_cause = phy->ops->interrupt_handler(phy);
435 if (phy_cause & cphy_cause_link_change)
436 link_changed(adapter, 0);
437 }
438 break;
439 }
440 t1_tpi_write(adapter, A_ELMER0_INT_CAUSE, cause);
441 return 0;
442}
443
444/* Enables all interrupts. */
445void t1_interrupts_enable(adapter_t *adapter)
446{
447 unsigned int i;
448 u32 pl_intr;
449
450 adapter->slow_intr_mask = F_PL_INTR_SGE_ERR;
451
452 t1_sge_intr_enable(adapter->sge);
453 if (adapter->espi) {
454 adapter->slow_intr_mask |= F_PL_INTR_ESPI;
455 t1_espi_intr_enable(adapter->espi);
456 }
457
458 /* Enable MAC/PHY interrupts for each port. */
459 for_each_port(adapter, i) {
460 adapter->port[i].mac->ops->interrupt_enable(adapter->port[i].mac);
461 adapter->port[i].phy->ops->interrupt_enable(adapter->port[i].phy);
462 }
463
464 /* Enable PCIX & external chip interrupts on ASIC boards. */
465 pl_intr = readl(adapter->regs + A_PL_ENABLE);
466
467 /* PCI-X interrupts */
468 pci_write_config_dword(adapter->pdev, A_PCICFG_INTR_ENABLE,
469 0xffffffff);
470
471 adapter->slow_intr_mask |= F_PL_INTR_EXT | F_PL_INTR_PCIX;
472 pl_intr |= F_PL_INTR_EXT | F_PL_INTR_PCIX;
473 writel(pl_intr, adapter->regs + A_PL_ENABLE);
474}
475
476/* Disables all interrupts. */
477void t1_interrupts_disable(adapter_t* adapter)
478{
479 unsigned int i;
480
481 t1_sge_intr_disable(adapter->sge);
482 if (adapter->espi)
483 t1_espi_intr_disable(adapter->espi);
484
485 /* Disable MAC/PHY interrupts for each port. */
486 for_each_port(adapter, i) {
487 adapter->port[i].mac->ops->interrupt_disable(adapter->port[i].mac);
488 adapter->port[i].phy->ops->interrupt_disable(adapter->port[i].phy);
489 }
490
491 /* Disable PCIX & external chip interrupts. */
492 writel(0, adapter->regs + A_PL_ENABLE);
493
494 /* PCI-X interrupts */
495 pci_write_config_dword(adapter->pdev, A_PCICFG_INTR_ENABLE, 0);
496
497 adapter->slow_intr_mask = 0;
498}
499
500/* Clears all interrupts */
501void t1_interrupts_clear(adapter_t* adapter)
502{
503 unsigned int i;
504 u32 pl_intr;
505
506
507 t1_sge_intr_clear(adapter->sge);
508 if (adapter->espi)
509 t1_espi_intr_clear(adapter->espi);
510
511 /* Clear MAC/PHY interrupts for each port. */
512 for_each_port(adapter, i) {
513 adapter->port[i].mac->ops->interrupt_clear(adapter->port[i].mac);
514 adapter->port[i].phy->ops->interrupt_clear(adapter->port[i].phy);
515 }
516
517 /* Enable interrupts for external devices. */
518 pl_intr = readl(adapter->regs + A_PL_CAUSE);
519
520 writel(pl_intr | F_PL_INTR_EXT | F_PL_INTR_PCIX,
521 adapter->regs + A_PL_CAUSE);
522
523 /* PCI-X interrupts */
524 pci_write_config_dword(adapter->pdev, A_PCICFG_INTR_CAUSE, 0xffffffff);
525}
526
527/*
528 * Slow path interrupt handler for ASICs.
529 */
530int t1_slow_intr_handler(adapter_t *adapter)
531{
532 u32 cause = readl(adapter->regs + A_PL_CAUSE);
533
534 cause &= adapter->slow_intr_mask;
535 if (!cause)
536 return 0;
537 if (cause & F_PL_INTR_SGE_ERR)
538 t1_sge_intr_error_handler(adapter->sge);
539 if (cause & F_PL_INTR_ESPI)
540 t1_espi_intr_handler(adapter->espi);
541 if (cause & F_PL_INTR_PCIX)
542 t1_pci_intr_handler(adapter);
543 if (cause & F_PL_INTR_EXT)
544 t1_elmer0_ext_intr(adapter);
545
546 /* Clear the interrupts just processed. */
547 writel(cause, adapter->regs + A_PL_CAUSE);
548 (void)readl(adapter->regs + A_PL_CAUSE); /* flush writes */
549 return 1;
550}
551
552/* Pause deadlock avoidance parameters */
553#define DROP_MSEC 16
554#define DROP_PKTS_CNT 1
555
556static void set_csum_offload(adapter_t *adapter, u32 csum_bit, int enable)
557{
558 u32 val = readl(adapter->regs + A_TP_GLOBAL_CONFIG);
559
560 if (enable)
561 val |= csum_bit;
562 else
563 val &= ~csum_bit;
564 writel(val, adapter->regs + A_TP_GLOBAL_CONFIG);
565}
566
567void t1_tp_set_ip_checksum_offload(adapter_t *adapter, int enable)
568{
569 set_csum_offload(adapter, F_IP_CSUM, enable);
570}
571
572void t1_tp_set_udp_checksum_offload(adapter_t *adapter, int enable)
573{
574 set_csum_offload(adapter, F_UDP_CSUM, enable);
575}
576
577void t1_tp_set_tcp_checksum_offload(adapter_t *adapter, int enable)
578{
579 set_csum_offload(adapter, F_TCP_CSUM, enable);
580}
581
582static void t1_tp_reset(adapter_t *adapter, unsigned int tp_clk)
583{
584 u32 val;
585
586 val = F_TP_IN_CSPI_CPL | F_TP_IN_CSPI_CHECK_IP_CSUM |
587 F_TP_IN_CSPI_CHECK_TCP_CSUM | F_TP_IN_ESPI_ETHERNET;
588 val |= F_TP_IN_ESPI_CHECK_IP_CSUM |
589 F_TP_IN_ESPI_CHECK_TCP_CSUM;
590 writel(val, adapter->regs + A_TP_IN_CONFIG);
591 writel(F_TP_OUT_CSPI_CPL |
592 F_TP_OUT_ESPI_ETHERNET |
593 F_TP_OUT_ESPI_GENERATE_IP_CSUM |
594 F_TP_OUT_ESPI_GENERATE_TCP_CSUM,
595 adapter->regs + A_TP_OUT_CONFIG);
596
597 val = readl(adapter->regs + A_TP_GLOBAL_CONFIG);
598 val &= ~(F_IP_CSUM | F_UDP_CSUM | F_TCP_CSUM);
599 writel(val, adapter->regs + A_TP_GLOBAL_CONFIG);
600
601 /*
602 * Enable pause frame deadlock prevention.
603 */
604 if (is_T2(adapter)) {
605 u32 drop_ticks = DROP_MSEC * (tp_clk / 1000);
606
607 writel(F_ENABLE_TX_DROP | F_ENABLE_TX_ERROR |
608 V_DROP_TICKS_CNT(drop_ticks) |
609 V_NUM_PKTS_DROPPED(DROP_PKTS_CNT),
610 adapter->regs + A_TP_TX_DROP_CONFIG);
611 }
612
613 writel(F_TP_RESET, adapter->regs + A_TP_RESET);
614}
615
616int __devinit t1_get_board_rev(adapter_t *adapter, const struct board_info *bi,
617 struct adapter_params *p)
618{
619 p->chip_version = bi->chip_term;
620 if (p->chip_version == CHBT_TERM_T1 ||
621 p->chip_version == CHBT_TERM_T2) {
622 u32 val = readl(adapter->regs + A_TP_PC_CONFIG);
623
624 val = G_TP_PC_REV(val);
625 if (val == 2)
626 p->chip_revision = TERM_T1B;
627 else if (val == 3)
628 p->chip_revision = TERM_T2;
629 else
630 return -1;
631 } else
632 return -1;
633 return 0;
634}
635
636/*
637 * Enable board components other than the Chelsio chip, such as external MAC
638 * and PHY.
639 */
640static int board_init(adapter_t *adapter, const struct board_info *bi)
641{
642 switch (bi->board) {
643 case CHBT_BOARD_N110:
644 case CHBT_BOARD_N210:
645 writel(V_TPIPAR(0xf), adapter->regs + A_TPI_PAR);
646 t1_tpi_write(adapter, A_ELMER0_GPO, 0x800);
647 break;
648 }
649 return 0;
650}
651
652/*
653 * Initialize and configure the Terminator HW modules. Note that external
654 * MAC and PHYs are initialized separately.
655 */
656int t1_init_hw_modules(adapter_t *adapter)
657{
658 int err = -EIO;
659 const struct board_info *bi = board_info(adapter);
660
661 if (!bi->clock_mc4) {
662 u32 val = readl(adapter->regs + A_MC4_CFG);
663
664 writel(val | F_READY | F_MC4_SLOW, adapter->regs + A_MC4_CFG);
665 writel(F_M_BUS_ENABLE | F_TCAM_RESET,
666 adapter->regs + A_MC5_CONFIG);
667 }
668
669 if (adapter->espi && t1_espi_init(adapter->espi, bi->chip_mac,
670 bi->espi_nports))
671 goto out_err;
672
673 t1_tp_reset(adapter, bi->clock_core);
674
675 err = t1_sge_configure(adapter->sge, &adapter->params.sge);
676 if (err)
677 goto out_err;
678
679 err = 0;
680 out_err:
681 return err;
682}
683
684/*
685 * Determine a card's PCI mode.
686 */
687static void __devinit get_pci_mode(adapter_t *adapter, struct chelsio_pci_params *p)
688{
689 static unsigned short speed_map[] = { 33, 66, 100, 133 };
690 u32 pci_mode;
691
692 pci_read_config_dword(adapter->pdev, A_PCICFG_MODE, &pci_mode);
693 p->speed = speed_map[G_PCI_MODE_CLK(pci_mode)];
694 p->width = (pci_mode & F_PCI_MODE_64BIT) ? 64 : 32;
695 p->is_pcix = (pci_mode & F_PCI_MODE_PCIX) != 0;
696}
697
698/*
699 * Release the structures holding the SW per-Terminator-HW-module state.
700 */
701void t1_free_sw_modules(adapter_t *adapter)
702{
703 unsigned int i;
704
705 for_each_port(adapter, i) {
706 struct cmac *mac = adapter->port[i].mac;
707 struct cphy *phy = adapter->port[i].phy;
708
709 if (mac)
710 mac->ops->destroy(mac);
711 if (phy)
712 phy->ops->destroy(phy);
713 }
714
715 if (adapter->sge)
716 t1_sge_destroy(adapter->sge);
717 if (adapter->espi)
718 t1_espi_destroy(adapter->espi);
719}
720
721static void __devinit init_link_config(struct link_config *lc,
722 const struct board_info *bi)
723{
724 lc->supported = bi->caps;
725 lc->requested_speed = lc->speed = SPEED_INVALID;
726 lc->requested_duplex = lc->duplex = DUPLEX_INVALID;
727 lc->requested_fc = lc->fc = PAUSE_RX | PAUSE_TX;
728 if (lc->supported & SUPPORTED_Autoneg) {
729 lc->advertising = lc->supported;
730 lc->autoneg = AUTONEG_ENABLE;
731 lc->requested_fc |= PAUSE_AUTONEG;
732 } else {
733 lc->advertising = 0;
734 lc->autoneg = AUTONEG_DISABLE;
735 }
736}
737
738
739/*
740 * Allocate and initialize the data structures that hold the SW state of
741 * the Terminator HW modules.
742 */
743int __devinit t1_init_sw_modules(adapter_t *adapter,
744 const struct board_info *bi)
745{
746 unsigned int i;
747
748 adapter->params.brd_info = bi;
749 adapter->params.nports = bi->port_number;
750 adapter->params.stats_update_period = bi->gmac->stats_update_period;
751
752 adapter->sge = t1_sge_create(adapter, &adapter->params.sge);
753 if (!adapter->sge) {
754 CH_ERR("%s: SGE initialization failed\n",
755 adapter->name);
756 goto error;
757 }
758
759 if (bi->espi_nports && !(adapter->espi = t1_espi_create(adapter))) {
760 CH_ERR("%s: ESPI initialization failed\n",
761 adapter->name);
762 goto error;
763 }
764
765 board_init(adapter, bi);
766 bi->mdio_ops->init(adapter, bi);
767 if (bi->gphy->reset)
768 bi->gphy->reset(adapter);
769 if (bi->gmac->reset)
770 bi->gmac->reset(adapter);
771
772 for_each_port(adapter, i) {
773 u8 hw_addr[6];
774 struct cmac *mac;
775 int phy_addr = bi->mdio_phybaseaddr + i;
776
777 adapter->port[i].phy = bi->gphy->create(adapter, phy_addr,
778 bi->mdio_ops);
779 if (!adapter->port[i].phy) {
780 CH_ERR("%s: PHY %d initialization failed\n",
781 adapter->name, i);
782 goto error;
783 }
784
785 adapter->port[i].mac = mac = bi->gmac->create(adapter, i);
786 if (!mac) {
787 CH_ERR("%s: MAC %d initialization failed\n",
788 adapter->name, i);
789 goto error;
790 }
791
792 /*
793 * Get the port's MAC addresses either from the EEPROM if one
794 * exists or the one hardcoded in the MAC.
795 */
796 if (vpd_macaddress_get(adapter, i, hw_addr)) {
797 CH_ERR("%s: could not read MAC address from VPD ROM\n",
798 adapter->port[i].dev->name);
799 goto error;
800 }
801 memcpy(adapter->port[i].dev->dev_addr, hw_addr, ETH_ALEN);
802 init_link_config(&adapter->port[i].link_config, bi);
803 }
804
805 get_pci_mode(adapter, &adapter->params.pci);
806 t1_interrupts_clear(adapter);
807 return 0;
808
809 error:
810 t1_free_sw_modules(adapter);
811 return -1;
812}
diff --git a/drivers/net/chelsio/suni1x10gexp_regs.h b/drivers/net/chelsio/suni1x10gexp_regs.h
new file mode 100644
index 000000000000..81816c2b708a
--- /dev/null
+++ b/drivers/net/chelsio/suni1x10gexp_regs.h
@@ -0,0 +1,213 @@
1/*****************************************************************************
2 * *
3 * File: suni1x10gexp_regs.h *
4 * $Revision: 1.9 $ *
5 * $Date: 2005/06/22 00:17:04 $ *
6 * Description: *
7 * PMC/SIERRA (pm3393) MAC-PHY functionality. *
8 * part of the Chelsio 10Gb Ethernet Driver. *
9 * *
10 * This program is free software; you can redistribute it and/or modify *
11 * it under the terms of the GNU General Public License, version 2, as *
12 * published by the Free Software Foundation. *
13 * *
14 * You should have received a copy of the GNU General Public License along *
15 * with this program; if not, write to the Free Software Foundation, Inc., *
16 * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
17 * *
18 * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED *
19 * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF *
20 * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. *
21 * *
22 * http://www.chelsio.com *
23 * *
24 * Maintainers: maintainers@chelsio.com *
25 * *
26 * Authors: PMC/SIERRA *
27 * *
28 * History: *
29 * *
30 ****************************************************************************/
31
32#ifndef _CXGB_SUNI1x10GEXP_REGS_H_
33#define _CXGB_SUNI1x10GEXP_REGS_H_
34
35/******************************************************************************/
36/** S/UNI-1x10GE-XP REGISTER ADDRESS MAP **/
37/******************************************************************************/
38/* Refer to the Register Bit Masks bellow for the naming of each register and */
39/* to the S/UNI-1x10GE-XP Data Sheet for the signification of each bit */
40/******************************************************************************/
41
42#define SUNI1x10GEXP_REG_DEVICE_STATUS 0x0004
43#define SUNI1x10GEXP_REG_MASTER_INTERRUPT_STATUS 0x000D
44#define SUNI1x10GEXP_REG_GLOBAL_INTERRUPT_ENABLE 0x000E
45#define SUNI1x10GEXP_REG_SERDES_3125_INTERRUPT_ENABLE 0x0102
46#define SUNI1x10GEXP_REG_SERDES_3125_INTERRUPT_STATUS 0x0104
47#define SUNI1x10GEXP_REG_RXXG_CONFIG_1 0x2040
48#define SUNI1x10GEXP_REG_RXXG_CONFIG_3 0x2042
49#define SUNI1x10GEXP_REG_RXXG_INTERRUPT 0x2043
50#define SUNI1x10GEXP_REG_RXXG_MAX_FRAME_LENGTH 0x2045
51#define SUNI1x10GEXP_REG_RXXG_SA_15_0 0x2046
52#define SUNI1x10GEXP_REG_RXXG_SA_31_16 0x2047
53#define SUNI1x10GEXP_REG_RXXG_SA_47_32 0x2048
54#define SUNI1x10GEXP_REG_RXXG_EXACT_MATCH_ADDR_1_LOW 0x204D
55#define SUNI1x10GEXP_REG_RXXG_EXACT_MATCH_ADDR_1_MID 0x204E
56#define SUNI1x10GEXP_REG_RXXG_EXACT_MATCH_ADDR_1_HIGH 0x204F
57#define SUNI1x10GEXP_REG_RXXG_MULTICAST_HASH_LOW 0x206A
58#define SUNI1x10GEXP_REG_RXXG_MULTICAST_HASH_MIDLOW 0x206B
59#define SUNI1x10GEXP_REG_RXXG_MULTICAST_HASH_MIDHIGH 0x206C
60#define SUNI1x10GEXP_REG_RXXG_MULTICAST_HASH_HIGH 0x206D
61#define SUNI1x10GEXP_REG_RXXG_ADDRESS_FILTER_CONTROL_0 0x206E
62#define SUNI1x10GEXP_REG_RXXG_ADDRESS_FILTER_CONTROL_2 0x2070
63#define SUNI1x10GEXP_REG_XRF_INTERRUPT_ENABLE 0x2088
64#define SUNI1x10GEXP_REG_XRF_INTERRUPT_STATUS 0x2089
65#define SUNI1x10GEXP_REG_XRF_DIAG_INTERRUPT_ENABLE 0x208B
66#define SUNI1x10GEXP_REG_XRF_DIAG_INTERRUPT_STATUS 0x208C
67#define SUNI1x10GEXP_REG_RXOAM_INTERRUPT_ENABLE 0x20C7
68#define SUNI1x10GEXP_REG_RXOAM_INTERRUPT_STATUS 0x20C8
69#define SUNI1x10GEXP_REG_MSTAT_CONTROL 0x2100
70#define SUNI1x10GEXP_REG_MSTAT_COUNTER_ROLLOVER_0 0x2101
71#define SUNI1x10GEXP_REG_MSTAT_COUNTER_ROLLOVER_1 0x2102
72#define SUNI1x10GEXP_REG_MSTAT_COUNTER_ROLLOVER_2 0x2103
73#define SUNI1x10GEXP_REG_MSTAT_COUNTER_ROLLOVER_3 0x2104
74#define SUNI1x10GEXP_REG_MSTAT_INTERRUPT_MASK_0 0x2105
75#define SUNI1x10GEXP_REG_MSTAT_INTERRUPT_MASK_1 0x2106
76#define SUNI1x10GEXP_REG_MSTAT_INTERRUPT_MASK_2 0x2107
77#define SUNI1x10GEXP_REG_MSTAT_INTERRUPT_MASK_3 0x2108
78#define SUNI1x10GEXP_REG_MSTAT_COUNTER_0_LOW 0x2110
79#define SUNI1x10GEXP_REG_MSTAT_COUNTER_1_LOW 0x2114
80#define SUNI1x10GEXP_REG_MSTAT_COUNTER_4_LOW 0x2120
81#define SUNI1x10GEXP_REG_MSTAT_COUNTER_5_LOW 0x2124
82#define SUNI1x10GEXP_REG_MSTAT_COUNTER_6_LOW 0x2128
83#define SUNI1x10GEXP_REG_MSTAT_COUNTER_8_LOW 0x2130
84#define SUNI1x10GEXP_REG_MSTAT_COUNTER_10_LOW 0x2138
85#define SUNI1x10GEXP_REG_MSTAT_COUNTER_11_LOW 0x213C
86#define SUNI1x10GEXP_REG_MSTAT_COUNTER_12_LOW 0x2140
87#define SUNI1x10GEXP_REG_MSTAT_COUNTER_13_LOW 0x2144
88#define SUNI1x10GEXP_REG_MSTAT_COUNTER_15_LOW 0x214C
89#define SUNI1x10GEXP_REG_MSTAT_COUNTER_16_LOW 0x2150
90#define SUNI1x10GEXP_REG_MSTAT_COUNTER_17_LOW 0x2154
91#define SUNI1x10GEXP_REG_MSTAT_COUNTER_18_LOW 0x2158
92#define SUNI1x10GEXP_REG_MSTAT_COUNTER_33_LOW 0x2194
93#define SUNI1x10GEXP_REG_MSTAT_COUNTER_35_LOW 0x219C
94#define SUNI1x10GEXP_REG_MSTAT_COUNTER_36_LOW 0x21A0
95#define SUNI1x10GEXP_REG_MSTAT_COUNTER_38_LOW 0x21A8
96#define SUNI1x10GEXP_REG_MSTAT_COUNTER_40_LOW 0x21B0
97#define SUNI1x10GEXP_REG_MSTAT_COUNTER_42_LOW 0x21B8
98#define SUNI1x10GEXP_REG_MSTAT_COUNTER_43_LOW 0x21BC
99#define SUNI1x10GEXP_REG_IFLX_FIFO_OVERFLOW_ENABLE 0x2209
100#define SUNI1x10GEXP_REG_IFLX_FIFO_OVERFLOW_INTERRUPT 0x220A
101#define SUNI1x10GEXP_REG_PL4ODP_INTERRUPT_MASK 0x2282
102#define SUNI1x10GEXP_REG_PL4ODP_INTERRUPT 0x2283
103#define SUNI1x10GEXP_REG_PL4IO_LOCK_DETECT_STATUS 0x2300
104#define SUNI1x10GEXP_REG_PL4IO_LOCK_DETECT_CHANGE 0x2301
105#define SUNI1x10GEXP_REG_PL4IO_LOCK_DETECT_MASK 0x2302
106#define SUNI1x10GEXP_REG_TXXG_CONFIG_1 0x3040
107#define SUNI1x10GEXP_REG_TXXG_CONFIG_3 0x3042
108#define SUNI1x10GEXP_REG_TXXG_INTERRUPT 0x3043
109#define SUNI1x10GEXP_REG_TXXG_MAX_FRAME_SIZE 0x3045
110#define SUNI1x10GEXP_REG_TXXG_SA_15_0 0x3047
111#define SUNI1x10GEXP_REG_TXXG_SA_31_16 0x3048
112#define SUNI1x10GEXP_REG_TXXG_SA_47_32 0x3049
113#define SUNI1x10GEXP_REG_XTEF_INTERRUPT_STATUS 0x3084
114#define SUNI1x10GEXP_REG_XTEF_INTERRUPT_ENABLE 0x3085
115#define SUNI1x10GEXP_REG_TXOAM_INTERRUPT_ENABLE 0x30C6
116#define SUNI1x10GEXP_REG_TXOAM_INTERRUPT_STATUS 0x30C7
117#define SUNI1x10GEXP_REG_EFLX_FIFO_OVERFLOW_ERROR_ENABLE 0x320C
118#define SUNI1x10GEXP_REG_EFLX_FIFO_OVERFLOW_ERROR_INDICATION 0x320D
119#define SUNI1x10GEXP_REG_PL4IDU_INTERRUPT_MASK 0x3282
120#define SUNI1x10GEXP_REG_PL4IDU_INTERRUPT 0x3283
121
122/******************************************************************************/
123/* -- End register offset definitions -- */
124/******************************************************************************/
125
126/******************************************************************************/
127/** SUNI-1x10GE-XP REGISTER BIT MASKS **/
128/******************************************************************************/
129
130/*----------------------------------------------------------------------------
131 * Register 0x0004: S/UNI-1x10GE-XP Device Status
132 * Bit 9 TOP_SXRA_EXPIRED
133 * Bit 8 TOP_MDIO_BUSY
134 * Bit 7 TOP_DTRB
135 * Bit 6 TOP_EXPIRED
136 * Bit 5 TOP_PAUSED
137 * Bit 4 TOP_PL4_ID_DOOL
138 * Bit 3 TOP_PL4_IS_DOOL
139 * Bit 2 TOP_PL4_ID_ROOL
140 * Bit 1 TOP_PL4_IS_ROOL
141 * Bit 0 TOP_PL4_OUT_ROOL
142 *----------------------------------------------------------------------------*/
143#define SUNI1x10GEXP_BITMSK_TOP_SXRA_EXPIRED 0x0200
144#define SUNI1x10GEXP_BITMSK_TOP_EXPIRED 0x0040
145#define SUNI1x10GEXP_BITMSK_TOP_PL4_ID_DOOL 0x0010
146#define SUNI1x10GEXP_BITMSK_TOP_PL4_IS_DOOL 0x0008
147#define SUNI1x10GEXP_BITMSK_TOP_PL4_ID_ROOL 0x0004
148#define SUNI1x10GEXP_BITMSK_TOP_PL4_IS_ROOL 0x0002
149#define SUNI1x10GEXP_BITMSK_TOP_PL4_OUT_ROOL 0x0001
150
151/*----------------------------------------------------------------------------
152 * Register 0x000E:PM3393 Global interrupt enable
153 * Bit 15 TOP_INTE
154 *----------------------------------------------------------------------------*/
155#define SUNI1x10GEXP_BITMSK_TOP_INTE 0x8000
156
157/*----------------------------------------------------------------------------
158 * Register 0x2040: RXXG Configuration 1
159 * Bit 15 RXXG_RXEN
160 * Bit 14 RXXG_ROCF
161 * Bit 13 RXXG_PAD_STRIP
162 * Bit 10 RXXG_PUREP
163 * Bit 9 RXXG_LONGP
164 * Bit 8 RXXG_PARF
165 * Bit 7 RXXG_FLCHK
166 * Bit 5 RXXG_PASS_CTRL
167 * Bit 3 RXXG_CRC_STRIP
168 * Bit 2-0 RXXG_MIFG
169 *----------------------------------------------------------------------------*/
170#define SUNI1x10GEXP_BITMSK_RXXG_RXEN 0x8000
171#define SUNI1x10GEXP_BITMSK_RXXG_PUREP 0x0400
172#define SUNI1x10GEXP_BITMSK_RXXG_FLCHK 0x0080
173#define SUNI1x10GEXP_BITMSK_RXXG_CRC_STRIP 0x0008
174
175/*----------------------------------------------------------------------------
176 * Register 0x2070: RXXG Address Filter Control 2
177 * Bit 1 RXXG_PMODE
178 * Bit 0 RXXG_MHASH_EN
179 *----------------------------------------------------------------------------*/
180#define SUNI1x10GEXP_BITMSK_RXXG_PMODE 0x0002
181#define SUNI1x10GEXP_BITMSK_RXXG_MHASH_EN 0x0001
182
183/*----------------------------------------------------------------------------
184 * Register 0x2100: MSTAT Control
185 * Bit 2 MSTAT_WRITE
186 * Bit 1 MSTAT_CLEAR
187 * Bit 0 MSTAT_SNAP
188 *----------------------------------------------------------------------------*/
189#define SUNI1x10GEXP_BITMSK_MSTAT_CLEAR 0x0002
190#define SUNI1x10GEXP_BITMSK_MSTAT_SNAP 0x0001
191
192/*----------------------------------------------------------------------------
193 * Register 0x3040: TXXG Configuration Register 1
194 * Bit 15 TXXG_TXEN0
195 * Bit 13 TXXG_HOSTPAUSE
196 * Bit 12-7 TXXG_IPGT
197 * Bit 5 TXXG_32BIT_ALIGN
198 * Bit 4 TXXG_CRCEN
199 * Bit 3 TXXG_FCTX
200 * Bit 2 TXXG_FCRX
201 * Bit 1 TXXG_PADEN
202 * Bit 0 TXXG_SPRE
203 *----------------------------------------------------------------------------*/
204#define SUNI1x10GEXP_BITMSK_TXXG_TXEN0 0x8000
205#define SUNI1x10GEXP_BITOFF_TXXG_IPGT 7
206#define SUNI1x10GEXP_BITMSK_TXXG_32BIT_ALIGN 0x0020
207#define SUNI1x10GEXP_BITMSK_TXXG_CRCEN 0x0010
208#define SUNI1x10GEXP_BITMSK_TXXG_FCTX 0x0008
209#define SUNI1x10GEXP_BITMSK_TXXG_FCRX 0x0004
210#define SUNI1x10GEXP_BITMSK_TXXG_PADEN 0x0002
211
212#endif /* _CXGB_SUNI1x10GEXP_REGS_H_ */
213
diff --git a/drivers/net/e100.c b/drivers/net/e100.c
index d0fa2448761d..25cc20e415da 100644
--- a/drivers/net/e100.c
+++ b/drivers/net/e100.c
@@ -1,7 +1,7 @@
1/******************************************************************************* 1/*******************************************************************************
2 2
3 3
4 Copyright(c) 1999 - 2004 Intel Corporation. All rights reserved. 4 Copyright(c) 1999 - 2005 Intel Corporation. All rights reserved.
5 5
6 This program is free software; you can redistribute it and/or modify it 6 This program is free software; you can redistribute it and/or modify it
7 under the terms of the GNU General Public License as published by the Free 7 under the terms of the GNU General Public License as published by the Free
@@ -156,7 +156,7 @@
156 156
157#define DRV_NAME "e100" 157#define DRV_NAME "e100"
158#define DRV_EXT "-NAPI" 158#define DRV_EXT "-NAPI"
159#define DRV_VERSION "3.4.8-k2"DRV_EXT 159#define DRV_VERSION "3.4.14-k2"DRV_EXT
160#define DRV_DESCRIPTION "Intel(R) PRO/100 Network Driver" 160#define DRV_DESCRIPTION "Intel(R) PRO/100 Network Driver"
161#define DRV_COPYRIGHT "Copyright(c) 1999-2005 Intel Corporation" 161#define DRV_COPYRIGHT "Copyright(c) 1999-2005 Intel Corporation"
162#define PFX DRV_NAME ": " 162#define PFX DRV_NAME ": "
@@ -785,6 +785,7 @@ static int e100_eeprom_save(struct nic *nic, u16 start, u16 count)
785} 785}
786 786
787#define E100_WAIT_SCB_TIMEOUT 20000 /* we might have to wait 100ms!!! */ 787#define E100_WAIT_SCB_TIMEOUT 20000 /* we might have to wait 100ms!!! */
788#define E100_WAIT_SCB_FAST 20 /* delay like the old code */
788static inline int e100_exec_cmd(struct nic *nic, u8 cmd, dma_addr_t dma_addr) 789static inline int e100_exec_cmd(struct nic *nic, u8 cmd, dma_addr_t dma_addr)
789{ 790{
790 unsigned long flags; 791 unsigned long flags;
@@ -798,7 +799,7 @@ static inline int e100_exec_cmd(struct nic *nic, u8 cmd, dma_addr_t dma_addr)
798 if(likely(!readb(&nic->csr->scb.cmd_lo))) 799 if(likely(!readb(&nic->csr->scb.cmd_lo)))
799 break; 800 break;
800 cpu_relax(); 801 cpu_relax();
801 if(unlikely(i > (E100_WAIT_SCB_TIMEOUT >> 1))) 802 if(unlikely(i > E100_WAIT_SCB_FAST))
802 udelay(5); 803 udelay(5);
803 } 804 }
804 if(unlikely(i == E100_WAIT_SCB_TIMEOUT)) { 805 if(unlikely(i == E100_WAIT_SCB_TIMEOUT)) {
@@ -902,8 +903,8 @@ static void mdio_write(struct net_device *netdev, int addr, int reg, int data)
902 903
903static void e100_get_defaults(struct nic *nic) 904static void e100_get_defaults(struct nic *nic)
904{ 905{
905 struct param_range rfds = { .min = 16, .max = 256, .count = 64 }; 906 struct param_range rfds = { .min = 16, .max = 256, .count = 256 };
906 struct param_range cbs = { .min = 64, .max = 256, .count = 64 }; 907 struct param_range cbs = { .min = 64, .max = 256, .count = 128 };
907 908
908 pci_read_config_byte(nic->pdev, PCI_REVISION_ID, &nic->rev_id); 909 pci_read_config_byte(nic->pdev, PCI_REVISION_ID, &nic->rev_id);
909 /* MAC type is encoded as rev ID; exception: ICH is treated as 82559 */ 910 /* MAC type is encoded as rev ID; exception: ICH is treated as 82559 */
@@ -1006,25 +1007,213 @@ static void e100_configure(struct nic *nic, struct cb *cb, struct sk_buff *skb)
1006 c[16], c[17], c[18], c[19], c[20], c[21], c[22], c[23]); 1007 c[16], c[17], c[18], c[19], c[20], c[21], c[22], c[23]);
1007} 1008}
1008 1009
1010/********************************************************/
1011/* Micro code for 8086:1229 Rev 8 */
1012/********************************************************/
1013
1014/* Parameter values for the D101M B-step */
1015#define D101M_CPUSAVER_TIMER_DWORD 78
1016#define D101M_CPUSAVER_BUNDLE_DWORD 65
1017#define D101M_CPUSAVER_MIN_SIZE_DWORD 126
1018
1019#define D101M_B_RCVBUNDLE_UCODE \
1020{\
10210x00550215, 0xFFFF0437, 0xFFFFFFFF, 0x06A70789, 0xFFFFFFFF, 0x0558FFFF, \
10220x000C0001, 0x00101312, 0x000C0008, 0x00380216, \
10230x0010009C, 0x00204056, 0x002380CC, 0x00380056, \
10240x0010009C, 0x00244C0B, 0x00000800, 0x00124818, \
10250x00380438, 0x00000000, 0x00140000, 0x00380555, \
10260x00308000, 0x00100662, 0x00100561, 0x000E0408, \
10270x00134861, 0x000C0002, 0x00103093, 0x00308000, \
10280x00100624, 0x00100561, 0x000E0408, 0x00100861, \
10290x000C007E, 0x00222C21, 0x000C0002, 0x00103093, \
10300x00380C7A, 0x00080000, 0x00103090, 0x00380C7A, \
10310x00000000, 0x00000000, 0x00000000, 0x00000000, \
10320x0010009C, 0x00244C2D, 0x00010004, 0x00041000, \
10330x003A0437, 0x00044010, 0x0038078A, 0x00000000, \
10340x00100099, 0x00206C7A, 0x0010009C, 0x00244C48, \
10350x00130824, 0x000C0001, 0x00101213, 0x00260C75, \
10360x00041000, 0x00010004, 0x00130826, 0x000C0006, \
10370x002206A8, 0x0013C926, 0x00101313, 0x003806A8, \
10380x00000000, 0x00000000, 0x00000000, 0x00000000, \
10390x00000000, 0x00000000, 0x00000000, 0x00000000, \
10400x00080600, 0x00101B10, 0x00050004, 0x00100826, \
10410x00101210, 0x00380C34, 0x00000000, 0x00000000, \
10420x0021155B, 0x00100099, 0x00206559, 0x0010009C, \
10430x00244559, 0x00130836, 0x000C0000, 0x00220C62, \
10440x000C0001, 0x00101B13, 0x00229C0E, 0x00210C0E, \
10450x00226C0E, 0x00216C0E, 0x0022FC0E, 0x00215C0E, \
10460x00214C0E, 0x00380555, 0x00010004, 0x00041000, \
10470x00278C67, 0x00040800, 0x00018100, 0x003A0437, \
10480x00130826, 0x000C0001, 0x00220559, 0x00101313, \
10490x00380559, 0x00000000, 0x00000000, 0x00000000, \
10500x00000000, 0x00000000, 0x00000000, 0x00000000, \
10510x00000000, 0x00130831, 0x0010090B, 0x00124813, \
10520x000CFF80, 0x002606AB, 0x00041000, 0x00010004, \
10530x003806A8, 0x00000000, 0x00000000, 0x00000000, \
1054}
1055
1056/********************************************************/
1057/* Micro code for 8086:1229 Rev 9 */
1058/********************************************************/
1059
1060/* Parameter values for the D101S */
1061#define D101S_CPUSAVER_TIMER_DWORD 78
1062#define D101S_CPUSAVER_BUNDLE_DWORD 67
1063#define D101S_CPUSAVER_MIN_SIZE_DWORD 128
1064
1065#define D101S_RCVBUNDLE_UCODE \
1066{\
10670x00550242, 0xFFFF047E, 0xFFFFFFFF, 0x06FF0818, 0xFFFFFFFF, 0x05A6FFFF, \
10680x000C0001, 0x00101312, 0x000C0008, 0x00380243, \
10690x0010009C, 0x00204056, 0x002380D0, 0x00380056, \
10700x0010009C, 0x00244F8B, 0x00000800, 0x00124818, \
10710x0038047F, 0x00000000, 0x00140000, 0x003805A3, \
10720x00308000, 0x00100610, 0x00100561, 0x000E0408, \
10730x00134861, 0x000C0002, 0x00103093, 0x00308000, \
10740x00100624, 0x00100561, 0x000E0408, 0x00100861, \
10750x000C007E, 0x00222FA1, 0x000C0002, 0x00103093, \
10760x00380F90, 0x00080000, 0x00103090, 0x00380F90, \
10770x00000000, 0x00000000, 0x00000000, 0x00000000, \
10780x0010009C, 0x00244FAD, 0x00010004, 0x00041000, \
10790x003A047E, 0x00044010, 0x00380819, 0x00000000, \
10800x00100099, 0x00206FFD, 0x0010009A, 0x0020AFFD, \
10810x0010009C, 0x00244FC8, 0x00130824, 0x000C0001, \
10820x00101213, 0x00260FF7, 0x00041000, 0x00010004, \
10830x00130826, 0x000C0006, 0x00220700, 0x0013C926, \
10840x00101313, 0x00380700, 0x00000000, 0x00000000, \
10850x00000000, 0x00000000, 0x00000000, 0x00000000, \
10860x00080600, 0x00101B10, 0x00050004, 0x00100826, \
10870x00101210, 0x00380FB6, 0x00000000, 0x00000000, \
10880x002115A9, 0x00100099, 0x002065A7, 0x0010009A, \
10890x0020A5A7, 0x0010009C, 0x002445A7, 0x00130836, \
10900x000C0000, 0x00220FE4, 0x000C0001, 0x00101B13, \
10910x00229F8E, 0x00210F8E, 0x00226F8E, 0x00216F8E, \
10920x0022FF8E, 0x00215F8E, 0x00214F8E, 0x003805A3, \
10930x00010004, 0x00041000, 0x00278FE9, 0x00040800, \
10940x00018100, 0x003A047E, 0x00130826, 0x000C0001, \
10950x002205A7, 0x00101313, 0x003805A7, 0x00000000, \
10960x00000000, 0x00000000, 0x00000000, 0x00000000, \
10970x00000000, 0x00000000, 0x00000000, 0x00130831, \
10980x0010090B, 0x00124813, 0x000CFF80, 0x00260703, \
10990x00041000, 0x00010004, 0x00380700 \
1100}
1101
1102/********************************************************/
1103/* Micro code for the 8086:1229 Rev F/10 */
1104/********************************************************/
1105
1106/* Parameter values for the D102 E-step */
1107#define D102_E_CPUSAVER_TIMER_DWORD 42
1108#define D102_E_CPUSAVER_BUNDLE_DWORD 54
1109#define D102_E_CPUSAVER_MIN_SIZE_DWORD 46
1110
1111#define D102_E_RCVBUNDLE_UCODE \
1112{\
11130x007D028F, 0x0E4204F9, 0x14ED0C85, 0x14FA14E9, 0x0EF70E36, 0x1FFF1FFF, \
11140x00E014B9, 0x00000000, 0x00000000, 0x00000000, \
11150x00E014BD, 0x00000000, 0x00000000, 0x00000000, \
11160x00E014D5, 0x00000000, 0x00000000, 0x00000000, \
11170x00000000, 0x00000000, 0x00000000, 0x00000000, \
11180x00E014C1, 0x00000000, 0x00000000, 0x00000000, \
11190x00000000, 0x00000000, 0x00000000, 0x00000000, \
11200x00000000, 0x00000000, 0x00000000, 0x00000000, \
11210x00000000, 0x00000000, 0x00000000, 0x00000000, \
11220x00E014C8, 0x00000000, 0x00000000, 0x00000000, \
11230x00200600, 0x00E014EE, 0x00000000, 0x00000000, \
11240x0030FF80, 0x00940E46, 0x00038200, 0x00102000, \
11250x00E00E43, 0x00000000, 0x00000000, 0x00000000, \
11260x00300006, 0x00E014FB, 0x00000000, 0x00000000, \
11270x00000000, 0x00000000, 0x00000000, 0x00000000, \
11280x00000000, 0x00000000, 0x00000000, 0x00000000, \
11290x00000000, 0x00000000, 0x00000000, 0x00000000, \
11300x00906E41, 0x00800E3C, 0x00E00E39, 0x00000000, \
11310x00906EFD, 0x00900EFD, 0x00E00EF8, 0x00000000, \
11320x00000000, 0x00000000, 0x00000000, 0x00000000, \
11330x00000000, 0x00000000, 0x00000000, 0x00000000, \
11340x00000000, 0x00000000, 0x00000000, 0x00000000, \
11350x00000000, 0x00000000, 0x00000000, 0x00000000, \
11360x00000000, 0x00000000, 0x00000000, 0x00000000, \
11370x00000000, 0x00000000, 0x00000000, 0x00000000, \
11380x00000000, 0x00000000, 0x00000000, 0x00000000, \
11390x00000000, 0x00000000, 0x00000000, 0x00000000, \
11400x00000000, 0x00000000, 0x00000000, 0x00000000, \
11410x00000000, 0x00000000, 0x00000000, 0x00000000, \
11420x00000000, 0x00000000, 0x00000000, 0x00000000, \
11430x00000000, 0x00000000, 0x00000000, 0x00000000, \
11440x00000000, 0x00000000, 0x00000000, 0x00000000, \
11450x00000000, 0x00000000, 0x00000000, 0x00000000, \
1146}
1147
1009static void e100_load_ucode(struct nic *nic, struct cb *cb, struct sk_buff *skb) 1148static void e100_load_ucode(struct nic *nic, struct cb *cb, struct sk_buff *skb)
1010{ 1149{
1011 int i; 1150/* *INDENT-OFF* */
1012 static const u32 ucode[UCODE_SIZE] = { 1151 static struct {
1013 /* NFS packets are misinterpreted as TCO packets and 1152 u32 ucode[UCODE_SIZE + 1];
1014 * incorrectly routed to the BMC over SMBus. This 1153 u8 mac;
1015 * microcode patch checks the fragmented IP bit in the 1154 u8 timer_dword;
1016 * NFS/UDP header to distinguish between NFS and TCO. */ 1155 u8 bundle_dword;
1017 0x0EF70E36, 0x1FFF1FFF, 0x1FFF1FFF, 0x1FFF1FFF, 0x1FFF1FFF, 1156 u8 min_size_dword;
1018 0x1FFF1FFF, 0x00906E41, 0x00800E3C, 0x00E00E39, 0x00000000, 1157 } ucode_opts[] = {
1019 0x00906EFD, 0x00900EFD, 0x00E00EF8, 1158 { D101M_B_RCVBUNDLE_UCODE,
1020 }; 1159 mac_82559_D101M,
1160 D101M_CPUSAVER_TIMER_DWORD,
1161 D101M_CPUSAVER_BUNDLE_DWORD,
1162 D101M_CPUSAVER_MIN_SIZE_DWORD },
1163 { D101S_RCVBUNDLE_UCODE,
1164 mac_82559_D101S,
1165 D101S_CPUSAVER_TIMER_DWORD,
1166 D101S_CPUSAVER_BUNDLE_DWORD,
1167 D101S_CPUSAVER_MIN_SIZE_DWORD },
1168 { D102_E_RCVBUNDLE_UCODE,
1169 mac_82551_F,
1170 D102_E_CPUSAVER_TIMER_DWORD,
1171 D102_E_CPUSAVER_BUNDLE_DWORD,
1172 D102_E_CPUSAVER_MIN_SIZE_DWORD },
1173 { D102_E_RCVBUNDLE_UCODE,
1174 mac_82551_10,
1175 D102_E_CPUSAVER_TIMER_DWORD,
1176 D102_E_CPUSAVER_BUNDLE_DWORD,
1177 D102_E_CPUSAVER_MIN_SIZE_DWORD },
1178 { {0}, 0, 0, 0, 0}
1179 }, *opts;
1180/* *INDENT-ON* */
1181
1182#define BUNDLESMALL 1
1183#define BUNDLEMAX 50
1184#define INTDELAY 15000
1185
1186 opts = ucode_opts;
1187
1188 /* do not load u-code for ICH devices */
1189 if (nic->flags & ich)
1190 return;
1191
1192 /* Search for ucode match against h/w rev_id */
1193 while (opts->mac) {
1194 if (nic->mac == opts->mac) {
1195 int i;
1196 u32 *ucode = opts->ucode;
1197
1198 /* Insert user-tunable settings */
1199 ucode[opts->timer_dword] &= 0xFFFF0000;
1200 ucode[opts->timer_dword] |=
1201 (u16) INTDELAY;
1202 ucode[opts->bundle_dword] &= 0xFFFF0000;
1203 ucode[opts->bundle_dword] |= (u16) BUNDLEMAX;
1204 ucode[opts->min_size_dword] &= 0xFFFF0000;
1205 ucode[opts->min_size_dword] |=
1206 (BUNDLESMALL) ? 0xFFFF : 0xFF80;
1207
1208 for(i = 0; i < UCODE_SIZE; i++)
1209 cb->u.ucode[i] = cpu_to_le32(ucode[i]);
1210 cb->command = cpu_to_le16(cb_ucode);
1211 return;
1212 }
1213 opts++;
1214 }
1021 1215
1022 if(nic->mac == mac_82551_F || nic->mac == mac_82551_10) { 1216 cb->command = cpu_to_le16(cb_nop);
1023 for(i = 0; i < UCODE_SIZE; i++)
1024 cb->u.ucode[i] = cpu_to_le32(ucode[i]);
1025 cb->command = cpu_to_le16(cb_ucode);
1026 } else
1027 cb->command = cpu_to_le16(cb_nop);
1028} 1217}
1029 1218
1030static void e100_setup_iaaddr(struct nic *nic, struct cb *cb, 1219static void e100_setup_iaaddr(struct nic *nic, struct cb *cb,
@@ -1307,14 +1496,15 @@ static inline void e100_xmit_prepare(struct nic *nic, struct cb *cb,
1307{ 1496{
1308 cb->command = nic->tx_command; 1497 cb->command = nic->tx_command;
1309 /* interrupt every 16 packets regardless of delay */ 1498 /* interrupt every 16 packets regardless of delay */
1310 if((nic->cbs_avail & ~15) == nic->cbs_avail) cb->command |= cb_i; 1499 if((nic->cbs_avail & ~15) == nic->cbs_avail)
1500 cb->command |= cpu_to_le16(cb_i);
1311 cb->u.tcb.tbd_array = cb->dma_addr + offsetof(struct cb, u.tcb.tbd); 1501 cb->u.tcb.tbd_array = cb->dma_addr + offsetof(struct cb, u.tcb.tbd);
1312 cb->u.tcb.tcb_byte_count = 0; 1502 cb->u.tcb.tcb_byte_count = 0;
1313 cb->u.tcb.threshold = nic->tx_threshold; 1503 cb->u.tcb.threshold = nic->tx_threshold;
1314 cb->u.tcb.tbd_count = 1; 1504 cb->u.tcb.tbd_count = 1;
1315 cb->u.tcb.tbd.buf_addr = cpu_to_le32(pci_map_single(nic->pdev, 1505 cb->u.tcb.tbd.buf_addr = cpu_to_le32(pci_map_single(nic->pdev,
1316 skb->data, skb->len, PCI_DMA_TODEVICE)); 1506 skb->data, skb->len, PCI_DMA_TODEVICE));
1317 // check for mapping failure? 1507 /* check for mapping failure? */
1318 cb->u.tcb.tbd.size = cpu_to_le16(skb->len); 1508 cb->u.tcb.tbd.size = cpu_to_le16(skb->len);
1319} 1509}
1320 1510
@@ -1539,7 +1729,7 @@ static inline int e100_rx_indicate(struct nic *nic, struct rx *rx,
1539 /* Don't indicate if hardware indicates errors */ 1729 /* Don't indicate if hardware indicates errors */
1540 nic->net_stats.rx_dropped++; 1730 nic->net_stats.rx_dropped++;
1541 dev_kfree_skb_any(skb); 1731 dev_kfree_skb_any(skb);
1542 } else if(actual_size > nic->netdev->mtu + VLAN_ETH_HLEN) { 1732 } else if(actual_size > ETH_DATA_LEN + VLAN_ETH_HLEN) {
1543 /* Don't indicate oversized frames */ 1733 /* Don't indicate oversized frames */
1544 nic->rx_over_length_errors++; 1734 nic->rx_over_length_errors++;
1545 nic->net_stats.rx_dropped++; 1735 nic->net_stats.rx_dropped++;
@@ -1706,6 +1896,7 @@ static int e100_poll(struct net_device *netdev, int *budget)
1706static void e100_netpoll(struct net_device *netdev) 1896static void e100_netpoll(struct net_device *netdev)
1707{ 1897{
1708 struct nic *nic = netdev_priv(netdev); 1898 struct nic *nic = netdev_priv(netdev);
1899
1709 e100_disable_irq(nic); 1900 e100_disable_irq(nic);
1710 e100_intr(nic->pdev->irq, netdev, NULL); 1901 e100_intr(nic->pdev->irq, netdev, NULL);
1711 e100_tx_clean(nic); 1902 e100_tx_clean(nic);
@@ -2108,6 +2299,8 @@ static void e100_diag_test(struct net_device *netdev,
2108 } 2299 }
2109 for(i = 0; i < E100_TEST_LEN; i++) 2300 for(i = 0; i < E100_TEST_LEN; i++)
2110 test->flags |= data[i] ? ETH_TEST_FL_FAILED : 0; 2301 test->flags |= data[i] ? ETH_TEST_FL_FAILED : 0;
2302
2303 msleep_interruptible(4 * 1000);
2111} 2304}
2112 2305
2113static int e100_phys_id(struct net_device *netdev, u32 data) 2306static int e100_phys_id(struct net_device *netdev, u32 data)
diff --git a/drivers/net/hamradio/bpqether.c b/drivers/net/hamradio/bpqether.c
index ba9f0580e1f9..2946e037a9b1 100644
--- a/drivers/net/hamradio/bpqether.c
+++ b/drivers/net/hamradio/bpqether.c
@@ -98,7 +98,7 @@ static char bcast_addr[6]={0xFF,0xFF,0xFF,0xFF,0xFF,0xFF};
98 98
99static char bpq_eth_addr[6]; 99static char bpq_eth_addr[6];
100 100
101static int bpq_rcv(struct sk_buff *, struct net_device *, struct packet_type *); 101static int bpq_rcv(struct sk_buff *, struct net_device *, struct packet_type *, struct net_device *);
102static int bpq_device_event(struct notifier_block *, unsigned long, void *); 102static int bpq_device_event(struct notifier_block *, unsigned long, void *);
103static const char *bpq_print_ethaddr(const unsigned char *); 103static const char *bpq_print_ethaddr(const unsigned char *);
104 104
@@ -165,7 +165,7 @@ static inline int dev_is_ethdev(struct net_device *dev)
165/* 165/*
166 * Receive an AX.25 frame via an ethernet interface. 166 * Receive an AX.25 frame via an ethernet interface.
167 */ 167 */
168static int bpq_rcv(struct sk_buff *skb, struct net_device *dev, struct packet_type *ptype) 168static int bpq_rcv(struct sk_buff *skb, struct net_device *dev, struct packet_type *ptype, struct net_device *orig_dev)
169{ 169{
170 int len; 170 int len;
171 char * ptr; 171 char * ptr;
diff --git a/drivers/net/ibmveth.c b/drivers/net/ibmveth.c
index c39b0609742a..32d5fabd4b10 100644
--- a/drivers/net/ibmveth.c
+++ b/drivers/net/ibmveth.c
@@ -1144,7 +1144,7 @@ static void ibmveth_proc_unregister_driver(void)
1144 1144
1145static struct vio_device_id ibmveth_device_table[] __devinitdata= { 1145static struct vio_device_id ibmveth_device_table[] __devinitdata= {
1146 { "network", "IBM,l-lan"}, 1146 { "network", "IBM,l-lan"},
1147 { 0,} 1147 { "", "" }
1148}; 1148};
1149 1149
1150MODULE_DEVICE_TABLE(vio, ibmveth_device_table); 1150MODULE_DEVICE_TABLE(vio, ibmveth_device_table);
diff --git a/drivers/net/iseries_veth.c b/drivers/net/iseries_veth.c
index 55af32e9bf08..dc5d089bf184 100644
--- a/drivers/net/iseries_veth.c
+++ b/drivers/net/iseries_veth.c
@@ -79,12 +79,55 @@
79#include <asm/iommu.h> 79#include <asm/iommu.h>
80#include <asm/vio.h> 80#include <asm/vio.h>
81 81
82#include "iseries_veth.h" 82#undef DEBUG
83 83
84MODULE_AUTHOR("Kyle Lucke <klucke@us.ibm.com>"); 84MODULE_AUTHOR("Kyle Lucke <klucke@us.ibm.com>");
85MODULE_DESCRIPTION("iSeries Virtual ethernet driver"); 85MODULE_DESCRIPTION("iSeries Virtual ethernet driver");
86MODULE_LICENSE("GPL"); 86MODULE_LICENSE("GPL");
87 87
88#define VETH_EVENT_CAP (0)
89#define VETH_EVENT_FRAMES (1)
90#define VETH_EVENT_MONITOR (2)
91#define VETH_EVENT_FRAMES_ACK (3)
92
93#define VETH_MAX_ACKS_PER_MSG (20)
94#define VETH_MAX_FRAMES_PER_MSG (6)
95
96struct veth_frames_data {
97 u32 addr[VETH_MAX_FRAMES_PER_MSG];
98 u16 len[VETH_MAX_FRAMES_PER_MSG];
99 u32 eofmask;
100};
101#define VETH_EOF_SHIFT (32-VETH_MAX_FRAMES_PER_MSG)
102
103struct veth_frames_ack_data {
104 u16 token[VETH_MAX_ACKS_PER_MSG];
105};
106
107struct veth_cap_data {
108 u8 caps_version;
109 u8 rsvd1;
110 u16 num_buffers;
111 u16 ack_threshold;
112 u16 rsvd2;
113 u32 ack_timeout;
114 u32 rsvd3;
115 u64 rsvd4[3];
116};
117
118struct veth_lpevent {
119 struct HvLpEvent base_event;
120 union {
121 struct veth_cap_data caps_data;
122 struct veth_frames_data frames_data;
123 struct veth_frames_ack_data frames_ack_data;
124 } u;
125
126};
127
128#define DRV_NAME "iseries_veth"
129#define DRV_VERSION "2.0"
130
88#define VETH_NUMBUFFERS (120) 131#define VETH_NUMBUFFERS (120)
89#define VETH_ACKTIMEOUT (1000000) /* microseconds */ 132#define VETH_ACKTIMEOUT (1000000) /* microseconds */
90#define VETH_MAX_MCAST (12) 133#define VETH_MAX_MCAST (12)
@@ -113,9 +156,9 @@ MODULE_LICENSE("GPL");
113 156
114struct veth_msg { 157struct veth_msg {
115 struct veth_msg *next; 158 struct veth_msg *next;
116 struct VethFramesData data; 159 struct veth_frames_data data;
117 int token; 160 int token;
118 unsigned long in_use; 161 int in_use;
119 struct sk_buff *skb; 162 struct sk_buff *skb;
120 struct device *dev; 163 struct device *dev;
121}; 164};
@@ -125,23 +168,28 @@ struct veth_lpar_connection {
125 struct work_struct statemachine_wq; 168 struct work_struct statemachine_wq;
126 struct veth_msg *msgs; 169 struct veth_msg *msgs;
127 int num_events; 170 int num_events;
128 struct VethCapData local_caps; 171 struct veth_cap_data local_caps;
129 172
173 struct kobject kobject;
130 struct timer_list ack_timer; 174 struct timer_list ack_timer;
131 175
176 struct timer_list reset_timer;
177 unsigned int reset_timeout;
178 unsigned long last_contact;
179 int outstanding_tx;
180
132 spinlock_t lock; 181 spinlock_t lock;
133 unsigned long state; 182 unsigned long state;
134 HvLpInstanceId src_inst; 183 HvLpInstanceId src_inst;
135 HvLpInstanceId dst_inst; 184 HvLpInstanceId dst_inst;
136 struct VethLpEvent cap_event, cap_ack_event; 185 struct veth_lpevent cap_event, cap_ack_event;
137 u16 pending_acks[VETH_MAX_ACKS_PER_MSG]; 186 u16 pending_acks[VETH_MAX_ACKS_PER_MSG];
138 u32 num_pending_acks; 187 u32 num_pending_acks;
139 188
140 int num_ack_events; 189 int num_ack_events;
141 struct VethCapData remote_caps; 190 struct veth_cap_data remote_caps;
142 u32 ack_timeout; 191 u32 ack_timeout;
143 192
144 spinlock_t msg_stack_lock;
145 struct veth_msg *msg_stack_head; 193 struct veth_msg *msg_stack_head;
146}; 194};
147 195
@@ -151,15 +199,17 @@ struct veth_port {
151 u64 mac_addr; 199 u64 mac_addr;
152 HvLpIndexMap lpar_map; 200 HvLpIndexMap lpar_map;
153 201
154 spinlock_t pending_gate; 202 /* queue_lock protects the stopped_map and dev's queue. */
155 struct sk_buff *pending_skb; 203 spinlock_t queue_lock;
156 HvLpIndexMap pending_lpmask; 204 HvLpIndexMap stopped_map;
157 205
206 /* mcast_gate protects promiscuous, num_mcast & mcast_addr. */
158 rwlock_t mcast_gate; 207 rwlock_t mcast_gate;
159 int promiscuous; 208 int promiscuous;
160 int all_mcast;
161 int num_mcast; 209 int num_mcast;
162 u64 mcast_addr[VETH_MAX_MCAST]; 210 u64 mcast_addr[VETH_MAX_MCAST];
211
212 struct kobject kobject;
163}; 213};
164 214
165static HvLpIndex this_lp; 215static HvLpIndex this_lp;
@@ -168,44 +218,56 @@ static struct net_device *veth_dev[HVMAXARCHITECTEDVIRTUALLANS]; /* = 0 */
168 218
169static int veth_start_xmit(struct sk_buff *skb, struct net_device *dev); 219static int veth_start_xmit(struct sk_buff *skb, struct net_device *dev);
170static void veth_recycle_msg(struct veth_lpar_connection *, struct veth_msg *); 220static void veth_recycle_msg(struct veth_lpar_connection *, struct veth_msg *);
171static void veth_flush_pending(struct veth_lpar_connection *cnx); 221static void veth_wake_queues(struct veth_lpar_connection *cnx);
172static void veth_receive(struct veth_lpar_connection *, struct VethLpEvent *); 222static void veth_stop_queues(struct veth_lpar_connection *cnx);
173static void veth_timed_ack(unsigned long connectionPtr); 223static void veth_receive(struct veth_lpar_connection *, struct veth_lpevent *);
224static void veth_release_connection(struct kobject *kobject);
225static void veth_timed_ack(unsigned long ptr);
226static void veth_timed_reset(unsigned long ptr);
174 227
175/* 228/*
176 * Utility functions 229 * Utility functions
177 */ 230 */
178 231
179#define veth_printk(prio, fmt, args...) \ 232#define veth_info(fmt, args...) \
180 printk(prio "%s: " fmt, __FILE__, ## args) 233 printk(KERN_INFO DRV_NAME ": " fmt, ## args)
181 234
182#define veth_error(fmt, args...) \ 235#define veth_error(fmt, args...) \
183 printk(KERN_ERR "(%s:%3.3d) ERROR: " fmt, __FILE__, __LINE__ , ## args) 236 printk(KERN_ERR DRV_NAME ": Error: " fmt, ## args)
237
238#ifdef DEBUG
239#define veth_debug(fmt, args...) \
240 printk(KERN_DEBUG DRV_NAME ": " fmt, ## args)
241#else
242#define veth_debug(fmt, args...) do {} while (0)
243#endif
184 244
245/* You must hold the connection's lock when you call this function. */
185static inline void veth_stack_push(struct veth_lpar_connection *cnx, 246static inline void veth_stack_push(struct veth_lpar_connection *cnx,
186 struct veth_msg *msg) 247 struct veth_msg *msg)
187{ 248{
188 unsigned long flags;
189
190 spin_lock_irqsave(&cnx->msg_stack_lock, flags);
191 msg->next = cnx->msg_stack_head; 249 msg->next = cnx->msg_stack_head;
192 cnx->msg_stack_head = msg; 250 cnx->msg_stack_head = msg;
193 spin_unlock_irqrestore(&cnx->msg_stack_lock, flags);
194} 251}
195 252
253/* You must hold the connection's lock when you call this function. */
196static inline struct veth_msg *veth_stack_pop(struct veth_lpar_connection *cnx) 254static inline struct veth_msg *veth_stack_pop(struct veth_lpar_connection *cnx)
197{ 255{
198 unsigned long flags;
199 struct veth_msg *msg; 256 struct veth_msg *msg;
200 257
201 spin_lock_irqsave(&cnx->msg_stack_lock, flags);
202 msg = cnx->msg_stack_head; 258 msg = cnx->msg_stack_head;
203 if (msg) 259 if (msg)
204 cnx->msg_stack_head = cnx->msg_stack_head->next; 260 cnx->msg_stack_head = cnx->msg_stack_head->next;
205 spin_unlock_irqrestore(&cnx->msg_stack_lock, flags); 261
206 return msg; 262 return msg;
207} 263}
208 264
265/* You must hold the connection's lock when you call this function. */
266static inline int veth_stack_is_empty(struct veth_lpar_connection *cnx)
267{
268 return cnx->msg_stack_head == NULL;
269}
270
209static inline HvLpEvent_Rc 271static inline HvLpEvent_Rc
210veth_signalevent(struct veth_lpar_connection *cnx, u16 subtype, 272veth_signalevent(struct veth_lpar_connection *cnx, u16 subtype,
211 HvLpEvent_AckInd ackind, HvLpEvent_AckType acktype, 273 HvLpEvent_AckInd ackind, HvLpEvent_AckType acktype,
@@ -249,7 +311,7 @@ static int veth_allocate_events(HvLpIndex rlp, int number)
249 struct veth_allocation vc = { COMPLETION_INITIALIZER(vc.c), 0 }; 311 struct veth_allocation vc = { COMPLETION_INITIALIZER(vc.c), 0 };
250 312
251 mf_allocate_lp_events(rlp, HvLpEvent_Type_VirtualLan, 313 mf_allocate_lp_events(rlp, HvLpEvent_Type_VirtualLan,
252 sizeof(struct VethLpEvent), number, 314 sizeof(struct veth_lpevent), number,
253 &veth_complete_allocation, &vc); 315 &veth_complete_allocation, &vc);
254 wait_for_completion(&vc.c); 316 wait_for_completion(&vc.c);
255 317
@@ -257,6 +319,137 @@ static int veth_allocate_events(HvLpIndex rlp, int number)
257} 319}
258 320
259/* 321/*
322 * sysfs support
323 */
324
325struct veth_cnx_attribute {
326 struct attribute attr;
327 ssize_t (*show)(struct veth_lpar_connection *, char *buf);
328 ssize_t (*store)(struct veth_lpar_connection *, const char *buf);
329};
330
331static ssize_t veth_cnx_attribute_show(struct kobject *kobj,
332 struct attribute *attr, char *buf)
333{
334 struct veth_cnx_attribute *cnx_attr;
335 struct veth_lpar_connection *cnx;
336
337 cnx_attr = container_of(attr, struct veth_cnx_attribute, attr);
338 cnx = container_of(kobj, struct veth_lpar_connection, kobject);
339
340 if (!cnx_attr->show)
341 return -EIO;
342
343 return cnx_attr->show(cnx, buf);
344}
345
346#define CUSTOM_CNX_ATTR(_name, _format, _expression) \
347static ssize_t _name##_show(struct veth_lpar_connection *cnx, char *buf)\
348{ \
349 return sprintf(buf, _format, _expression); \
350} \
351struct veth_cnx_attribute veth_cnx_attr_##_name = __ATTR_RO(_name)
352
353#define SIMPLE_CNX_ATTR(_name) \
354 CUSTOM_CNX_ATTR(_name, "%lu\n", (unsigned long)cnx->_name)
355
356SIMPLE_CNX_ATTR(outstanding_tx);
357SIMPLE_CNX_ATTR(remote_lp);
358SIMPLE_CNX_ATTR(num_events);
359SIMPLE_CNX_ATTR(src_inst);
360SIMPLE_CNX_ATTR(dst_inst);
361SIMPLE_CNX_ATTR(num_pending_acks);
362SIMPLE_CNX_ATTR(num_ack_events);
363CUSTOM_CNX_ATTR(ack_timeout, "%d\n", jiffies_to_msecs(cnx->ack_timeout));
364CUSTOM_CNX_ATTR(reset_timeout, "%d\n", jiffies_to_msecs(cnx->reset_timeout));
365CUSTOM_CNX_ATTR(state, "0x%.4lX\n", cnx->state);
366CUSTOM_CNX_ATTR(last_contact, "%d\n", cnx->last_contact ?
367 jiffies_to_msecs(jiffies - cnx->last_contact) : 0);
368
369#define GET_CNX_ATTR(_name) (&veth_cnx_attr_##_name.attr)
370
371static struct attribute *veth_cnx_default_attrs[] = {
372 GET_CNX_ATTR(outstanding_tx),
373 GET_CNX_ATTR(remote_lp),
374 GET_CNX_ATTR(num_events),
375 GET_CNX_ATTR(reset_timeout),
376 GET_CNX_ATTR(last_contact),
377 GET_CNX_ATTR(state),
378 GET_CNX_ATTR(src_inst),
379 GET_CNX_ATTR(dst_inst),
380 GET_CNX_ATTR(num_pending_acks),
381 GET_CNX_ATTR(num_ack_events),
382 GET_CNX_ATTR(ack_timeout),
383 NULL
384};
385
386static struct sysfs_ops veth_cnx_sysfs_ops = {
387 .show = veth_cnx_attribute_show
388};
389
390static struct kobj_type veth_lpar_connection_ktype = {
391 .release = veth_release_connection,
392 .sysfs_ops = &veth_cnx_sysfs_ops,
393 .default_attrs = veth_cnx_default_attrs
394};
395
396struct veth_port_attribute {
397 struct attribute attr;
398 ssize_t (*show)(struct veth_port *, char *buf);
399 ssize_t (*store)(struct veth_port *, const char *buf);
400};
401
402static ssize_t veth_port_attribute_show(struct kobject *kobj,
403 struct attribute *attr, char *buf)
404{
405 struct veth_port_attribute *port_attr;
406 struct veth_port *port;
407
408 port_attr = container_of(attr, struct veth_port_attribute, attr);
409 port = container_of(kobj, struct veth_port, kobject);
410
411 if (!port_attr->show)
412 return -EIO;
413
414 return port_attr->show(port, buf);
415}
416
417#define CUSTOM_PORT_ATTR(_name, _format, _expression) \
418static ssize_t _name##_show(struct veth_port *port, char *buf) \
419{ \
420 return sprintf(buf, _format, _expression); \
421} \
422struct veth_port_attribute veth_port_attr_##_name = __ATTR_RO(_name)
423
424#define SIMPLE_PORT_ATTR(_name) \
425 CUSTOM_PORT_ATTR(_name, "%lu\n", (unsigned long)port->_name)
426
427SIMPLE_PORT_ATTR(promiscuous);
428SIMPLE_PORT_ATTR(num_mcast);
429CUSTOM_PORT_ATTR(lpar_map, "0x%X\n", port->lpar_map);
430CUSTOM_PORT_ATTR(stopped_map, "0x%X\n", port->stopped_map);
431CUSTOM_PORT_ATTR(mac_addr, "0x%lX\n", port->mac_addr);
432
433#define GET_PORT_ATTR(_name) (&veth_port_attr_##_name.attr)
434static struct attribute *veth_port_default_attrs[] = {
435 GET_PORT_ATTR(mac_addr),
436 GET_PORT_ATTR(lpar_map),
437 GET_PORT_ATTR(stopped_map),
438 GET_PORT_ATTR(promiscuous),
439 GET_PORT_ATTR(num_mcast),
440 NULL
441};
442
443static struct sysfs_ops veth_port_sysfs_ops = {
444 .show = veth_port_attribute_show
445};
446
447static struct kobj_type veth_port_ktype = {
448 .sysfs_ops = &veth_port_sysfs_ops,
449 .default_attrs = veth_port_default_attrs
450};
451
452/*
260 * LPAR connection code 453 * LPAR connection code
261 */ 454 */
262 455
@@ -266,7 +459,7 @@ static inline void veth_kick_statemachine(struct veth_lpar_connection *cnx)
266} 459}
267 460
268static void veth_take_cap(struct veth_lpar_connection *cnx, 461static void veth_take_cap(struct veth_lpar_connection *cnx,
269 struct VethLpEvent *event) 462 struct veth_lpevent *event)
270{ 463{
271 unsigned long flags; 464 unsigned long flags;
272 465
@@ -278,7 +471,7 @@ static void veth_take_cap(struct veth_lpar_connection *cnx,
278 HvLpEvent_Type_VirtualLan); 471 HvLpEvent_Type_VirtualLan);
279 472
280 if (cnx->state & VETH_STATE_GOTCAPS) { 473 if (cnx->state & VETH_STATE_GOTCAPS) {
281 veth_error("Received a second capabilities from lpar %d\n", 474 veth_error("Received a second capabilities from LPAR %d.\n",
282 cnx->remote_lp); 475 cnx->remote_lp);
283 event->base_event.xRc = HvLpEvent_Rc_BufferNotAvailable; 476 event->base_event.xRc = HvLpEvent_Rc_BufferNotAvailable;
284 HvCallEvent_ackLpEvent((struct HvLpEvent *) event); 477 HvCallEvent_ackLpEvent((struct HvLpEvent *) event);
@@ -291,13 +484,13 @@ static void veth_take_cap(struct veth_lpar_connection *cnx,
291} 484}
292 485
293static void veth_take_cap_ack(struct veth_lpar_connection *cnx, 486static void veth_take_cap_ack(struct veth_lpar_connection *cnx,
294 struct VethLpEvent *event) 487 struct veth_lpevent *event)
295{ 488{
296 unsigned long flags; 489 unsigned long flags;
297 490
298 spin_lock_irqsave(&cnx->lock, flags); 491 spin_lock_irqsave(&cnx->lock, flags);
299 if (cnx->state & VETH_STATE_GOTCAPACK) { 492 if (cnx->state & VETH_STATE_GOTCAPACK) {
300 veth_error("Received a second capabilities ack from lpar %d\n", 493 veth_error("Received a second capabilities ack from LPAR %d.\n",
301 cnx->remote_lp); 494 cnx->remote_lp);
302 } else { 495 } else {
303 memcpy(&cnx->cap_ack_event, event, 496 memcpy(&cnx->cap_ack_event, event,
@@ -309,19 +502,24 @@ static void veth_take_cap_ack(struct veth_lpar_connection *cnx,
309} 502}
310 503
311static void veth_take_monitor_ack(struct veth_lpar_connection *cnx, 504static void veth_take_monitor_ack(struct veth_lpar_connection *cnx,
312 struct VethLpEvent *event) 505 struct veth_lpevent *event)
313{ 506{
314 unsigned long flags; 507 unsigned long flags;
315 508
316 spin_lock_irqsave(&cnx->lock, flags); 509 spin_lock_irqsave(&cnx->lock, flags);
317 veth_printk(KERN_DEBUG, "Monitor ack returned for lpar %d\n", 510 veth_debug("cnx %d: lost connection.\n", cnx->remote_lp);
318 cnx->remote_lp); 511
319 cnx->state |= VETH_STATE_RESET; 512 /* Avoid kicking the statemachine once we're shutdown.
320 veth_kick_statemachine(cnx); 513 * It's unnecessary and it could break veth_stop_connection(). */
514
515 if (! (cnx->state & VETH_STATE_SHUTDOWN)) {
516 cnx->state |= VETH_STATE_RESET;
517 veth_kick_statemachine(cnx);
518 }
321 spin_unlock_irqrestore(&cnx->lock, flags); 519 spin_unlock_irqrestore(&cnx->lock, flags);
322} 520}
323 521
324static void veth_handle_ack(struct VethLpEvent *event) 522static void veth_handle_ack(struct veth_lpevent *event)
325{ 523{
326 HvLpIndex rlp = event->base_event.xTargetLp; 524 HvLpIndex rlp = event->base_event.xTargetLp;
327 struct veth_lpar_connection *cnx = veth_cnx[rlp]; 525 struct veth_lpar_connection *cnx = veth_cnx[rlp];
@@ -329,58 +527,67 @@ static void veth_handle_ack(struct VethLpEvent *event)
329 BUG_ON(! cnx); 527 BUG_ON(! cnx);
330 528
331 switch (event->base_event.xSubtype) { 529 switch (event->base_event.xSubtype) {
332 case VethEventTypeCap: 530 case VETH_EVENT_CAP:
333 veth_take_cap_ack(cnx, event); 531 veth_take_cap_ack(cnx, event);
334 break; 532 break;
335 case VethEventTypeMonitor: 533 case VETH_EVENT_MONITOR:
336 veth_take_monitor_ack(cnx, event); 534 veth_take_monitor_ack(cnx, event);
337 break; 535 break;
338 default: 536 default:
339 veth_error("Unknown ack type %d from lpar %d\n", 537 veth_error("Unknown ack type %d from LPAR %d.\n",
340 event->base_event.xSubtype, rlp); 538 event->base_event.xSubtype, rlp);
341 }; 539 };
342} 540}
343 541
344static void veth_handle_int(struct VethLpEvent *event) 542static void veth_handle_int(struct veth_lpevent *event)
345{ 543{
346 HvLpIndex rlp = event->base_event.xSourceLp; 544 HvLpIndex rlp = event->base_event.xSourceLp;
347 struct veth_lpar_connection *cnx = veth_cnx[rlp]; 545 struct veth_lpar_connection *cnx = veth_cnx[rlp];
348 unsigned long flags; 546 unsigned long flags;
349 int i; 547 int i, acked = 0;
350 548
351 BUG_ON(! cnx); 549 BUG_ON(! cnx);
352 550
353 switch (event->base_event.xSubtype) { 551 switch (event->base_event.xSubtype) {
354 case VethEventTypeCap: 552 case VETH_EVENT_CAP:
355 veth_take_cap(cnx, event); 553 veth_take_cap(cnx, event);
356 break; 554 break;
357 case VethEventTypeMonitor: 555 case VETH_EVENT_MONITOR:
358 /* do nothing... this'll hang out here til we're dead, 556 /* do nothing... this'll hang out here til we're dead,
359 * and the hypervisor will return it for us. */ 557 * and the hypervisor will return it for us. */
360 break; 558 break;
361 case VethEventTypeFramesAck: 559 case VETH_EVENT_FRAMES_ACK:
362 spin_lock_irqsave(&cnx->lock, flags); 560 spin_lock_irqsave(&cnx->lock, flags);
561
363 for (i = 0; i < VETH_MAX_ACKS_PER_MSG; ++i) { 562 for (i = 0; i < VETH_MAX_ACKS_PER_MSG; ++i) {
364 u16 msgnum = event->u.frames_ack_data.token[i]; 563 u16 msgnum = event->u.frames_ack_data.token[i];
365 564
366 if (msgnum < VETH_NUMBUFFERS) 565 if (msgnum < VETH_NUMBUFFERS) {
367 veth_recycle_msg(cnx, cnx->msgs + msgnum); 566 veth_recycle_msg(cnx, cnx->msgs + msgnum);
567 cnx->outstanding_tx--;
568 acked++;
569 }
570 }
571
572 if (acked > 0) {
573 cnx->last_contact = jiffies;
574 veth_wake_queues(cnx);
368 } 575 }
576
369 spin_unlock_irqrestore(&cnx->lock, flags); 577 spin_unlock_irqrestore(&cnx->lock, flags);
370 veth_flush_pending(cnx);
371 break; 578 break;
372 case VethEventTypeFrames: 579 case VETH_EVENT_FRAMES:
373 veth_receive(cnx, event); 580 veth_receive(cnx, event);
374 break; 581 break;
375 default: 582 default:
376 veth_error("Unknown interrupt type %d from lpar %d\n", 583 veth_error("Unknown interrupt type %d from LPAR %d.\n",
377 event->base_event.xSubtype, rlp); 584 event->base_event.xSubtype, rlp);
378 }; 585 };
379} 586}
380 587
381static void veth_handle_event(struct HvLpEvent *event, struct pt_regs *regs) 588static void veth_handle_event(struct HvLpEvent *event, struct pt_regs *regs)
382{ 589{
383 struct VethLpEvent *veth_event = (struct VethLpEvent *)event; 590 struct veth_lpevent *veth_event = (struct veth_lpevent *)event;
384 591
385 if (event->xFlags.xFunction == HvLpEvent_Function_Ack) 592 if (event->xFlags.xFunction == HvLpEvent_Function_Ack)
386 veth_handle_ack(veth_event); 593 veth_handle_ack(veth_event);
@@ -390,7 +597,7 @@ static void veth_handle_event(struct HvLpEvent *event, struct pt_regs *regs)
390 597
391static int veth_process_caps(struct veth_lpar_connection *cnx) 598static int veth_process_caps(struct veth_lpar_connection *cnx)
392{ 599{
393 struct VethCapData *remote_caps = &cnx->remote_caps; 600 struct veth_cap_data *remote_caps = &cnx->remote_caps;
394 int num_acks_needed; 601 int num_acks_needed;
395 602
396 /* Convert timer to jiffies */ 603 /* Convert timer to jiffies */
@@ -400,8 +607,8 @@ static int veth_process_caps(struct veth_lpar_connection *cnx)
400 || (remote_caps->ack_threshold > VETH_MAX_ACKS_PER_MSG) 607 || (remote_caps->ack_threshold > VETH_MAX_ACKS_PER_MSG)
401 || (remote_caps->ack_threshold == 0) 608 || (remote_caps->ack_threshold == 0)
402 || (cnx->ack_timeout == 0) ) { 609 || (cnx->ack_timeout == 0) ) {
403 veth_error("Received incompatible capabilities from lpar %d\n", 610 veth_error("Received incompatible capabilities from LPAR %d.\n",
404 cnx->remote_lp); 611 cnx->remote_lp);
405 return HvLpEvent_Rc_InvalidSubtypeData; 612 return HvLpEvent_Rc_InvalidSubtypeData;
406 } 613 }
407 614
@@ -418,8 +625,8 @@ static int veth_process_caps(struct veth_lpar_connection *cnx)
418 cnx->num_ack_events += num; 625 cnx->num_ack_events += num;
419 626
420 if (cnx->num_ack_events < num_acks_needed) { 627 if (cnx->num_ack_events < num_acks_needed) {
421 veth_error("Couldn't allocate enough ack events for lpar %d\n", 628 veth_error("Couldn't allocate enough ack events "
422 cnx->remote_lp); 629 "for LPAR %d.\n", cnx->remote_lp);
423 630
424 return HvLpEvent_Rc_BufferNotAvailable; 631 return HvLpEvent_Rc_BufferNotAvailable;
425 } 632 }
@@ -440,15 +647,15 @@ static void veth_statemachine(void *p)
440 647
441 restart: 648 restart:
442 if (cnx->state & VETH_STATE_RESET) { 649 if (cnx->state & VETH_STATE_RESET) {
443 int i;
444
445 del_timer(&cnx->ack_timer);
446
447 if (cnx->state & VETH_STATE_OPEN) 650 if (cnx->state & VETH_STATE_OPEN)
448 HvCallEvent_closeLpEventPath(cnx->remote_lp, 651 HvCallEvent_closeLpEventPath(cnx->remote_lp,
449 HvLpEvent_Type_VirtualLan); 652 HvLpEvent_Type_VirtualLan);
450 653
451 /* reset ack data */ 654 /*
655 * Reset ack data. This prevents the ack_timer actually
656 * doing anything, even if it runs one more time when
657 * we drop the lock below.
658 */
452 memset(&cnx->pending_acks, 0xff, sizeof (cnx->pending_acks)); 659 memset(&cnx->pending_acks, 0xff, sizeof (cnx->pending_acks));
453 cnx->num_pending_acks = 0; 660 cnx->num_pending_acks = 0;
454 661
@@ -458,14 +665,32 @@ static void veth_statemachine(void *p)
458 | VETH_STATE_SENTCAPACK | VETH_STATE_READY); 665 | VETH_STATE_SENTCAPACK | VETH_STATE_READY);
459 666
460 /* Clean up any leftover messages */ 667 /* Clean up any leftover messages */
461 if (cnx->msgs) 668 if (cnx->msgs) {
669 int i;
462 for (i = 0; i < VETH_NUMBUFFERS; ++i) 670 for (i = 0; i < VETH_NUMBUFFERS; ++i)
463 veth_recycle_msg(cnx, cnx->msgs + i); 671 veth_recycle_msg(cnx, cnx->msgs + i);
672 }
673
674 cnx->outstanding_tx = 0;
675 veth_wake_queues(cnx);
676
677 /* Drop the lock so we can do stuff that might sleep or
678 * take other locks. */
464 spin_unlock_irq(&cnx->lock); 679 spin_unlock_irq(&cnx->lock);
465 veth_flush_pending(cnx); 680
681 del_timer_sync(&cnx->ack_timer);
682 del_timer_sync(&cnx->reset_timer);
683
466 spin_lock_irq(&cnx->lock); 684 spin_lock_irq(&cnx->lock);
685
467 if (cnx->state & VETH_STATE_RESET) 686 if (cnx->state & VETH_STATE_RESET)
468 goto restart; 687 goto restart;
688
689 /* Hack, wait for the other end to reset itself. */
690 if (! (cnx->state & VETH_STATE_SHUTDOWN)) {
691 schedule_delayed_work(&cnx->statemachine_wq, 5 * HZ);
692 goto out;
693 }
469 } 694 }
470 695
471 if (cnx->state & VETH_STATE_SHUTDOWN) 696 if (cnx->state & VETH_STATE_SHUTDOWN)
@@ -488,7 +713,7 @@ static void veth_statemachine(void *p)
488 713
489 if ( (cnx->state & VETH_STATE_OPEN) 714 if ( (cnx->state & VETH_STATE_OPEN)
490 && !(cnx->state & VETH_STATE_SENTMON) ) { 715 && !(cnx->state & VETH_STATE_SENTMON) ) {
491 rc = veth_signalevent(cnx, VethEventTypeMonitor, 716 rc = veth_signalevent(cnx, VETH_EVENT_MONITOR,
492 HvLpEvent_AckInd_DoAck, 717 HvLpEvent_AckInd_DoAck,
493 HvLpEvent_AckType_DeferredAck, 718 HvLpEvent_AckType_DeferredAck,
494 0, 0, 0, 0, 0, 0); 719 0, 0, 0, 0, 0, 0);
@@ -498,9 +723,8 @@ static void veth_statemachine(void *p)
498 } else { 723 } else {
499 if ( (rc != HvLpEvent_Rc_PartitionDead) 724 if ( (rc != HvLpEvent_Rc_PartitionDead)
500 && (rc != HvLpEvent_Rc_PathClosed) ) 725 && (rc != HvLpEvent_Rc_PathClosed) )
501 veth_error("Error sending monitor to " 726 veth_error("Error sending monitor to LPAR %d, "
502 "lpar %d, rc=%x\n", 727 "rc = %d\n", rlp, rc);
503 rlp, (int) rc);
504 728
505 /* Oh well, hope we get a cap from the other 729 /* Oh well, hope we get a cap from the other
506 * end and do better when that kicks us */ 730 * end and do better when that kicks us */
@@ -512,7 +736,7 @@ static void veth_statemachine(void *p)
512 && !(cnx->state & VETH_STATE_SENTCAPS)) { 736 && !(cnx->state & VETH_STATE_SENTCAPS)) {
513 u64 *rawcap = (u64 *)&cnx->local_caps; 737 u64 *rawcap = (u64 *)&cnx->local_caps;
514 738
515 rc = veth_signalevent(cnx, VethEventTypeCap, 739 rc = veth_signalevent(cnx, VETH_EVENT_CAP,
516 HvLpEvent_AckInd_DoAck, 740 HvLpEvent_AckInd_DoAck,
517 HvLpEvent_AckType_ImmediateAck, 741 HvLpEvent_AckType_ImmediateAck,
518 0, rawcap[0], rawcap[1], rawcap[2], 742 0, rawcap[0], rawcap[1], rawcap[2],
@@ -523,9 +747,9 @@ static void veth_statemachine(void *p)
523 } else { 747 } else {
524 if ( (rc != HvLpEvent_Rc_PartitionDead) 748 if ( (rc != HvLpEvent_Rc_PartitionDead)
525 && (rc != HvLpEvent_Rc_PathClosed) ) 749 && (rc != HvLpEvent_Rc_PathClosed) )
526 veth_error("Error sending caps to " 750 veth_error("Error sending caps to LPAR %d, "
527 "lpar %d, rc=%x\n", 751 "rc = %d\n", rlp, rc);
528 rlp, (int) rc); 752
529 /* Oh well, hope we get a cap from the other 753 /* Oh well, hope we get a cap from the other
530 * end and do better when that kicks us */ 754 * end and do better when that kicks us */
531 goto out; 755 goto out;
@@ -534,7 +758,7 @@ static void veth_statemachine(void *p)
534 758
535 if ((cnx->state & VETH_STATE_GOTCAPS) 759 if ((cnx->state & VETH_STATE_GOTCAPS)
536 && !(cnx->state & VETH_STATE_SENTCAPACK)) { 760 && !(cnx->state & VETH_STATE_SENTCAPACK)) {
537 struct VethCapData *remote_caps = &cnx->remote_caps; 761 struct veth_cap_data *remote_caps = &cnx->remote_caps;
538 762
539 memcpy(remote_caps, &cnx->cap_event.u.caps_data, 763 memcpy(remote_caps, &cnx->cap_event.u.caps_data,
540 sizeof(*remote_caps)); 764 sizeof(*remote_caps));
@@ -565,10 +789,8 @@ static void veth_statemachine(void *p)
565 add_timer(&cnx->ack_timer); 789 add_timer(&cnx->ack_timer);
566 cnx->state |= VETH_STATE_READY; 790 cnx->state |= VETH_STATE_READY;
567 } else { 791 } else {
568 veth_printk(KERN_ERR, "Caps rejected (rc=%d) by " 792 veth_error("Caps rejected by LPAR %d, rc = %d\n",
569 "lpar %d\n", 793 rlp, cnx->cap_ack_event.base_event.xRc);
570 cnx->cap_ack_event.base_event.xRc,
571 rlp);
572 goto cant_cope; 794 goto cant_cope;
573 } 795 }
574 } 796 }
@@ -581,8 +803,8 @@ static void veth_statemachine(void *p)
581 /* FIXME: we get here if something happens we really can't 803 /* FIXME: we get here if something happens we really can't
582 * cope with. The link will never work once we get here, and 804 * cope with. The link will never work once we get here, and
583 * all we can do is not lock the rest of the system up */ 805 * all we can do is not lock the rest of the system up */
584 veth_error("Badness on connection to lpar %d (state=%04lx) " 806 veth_error("Unrecoverable error on connection to LPAR %d, shutting down"
585 " - shutting down\n", rlp, cnx->state); 807 " (state = 0x%04lx)\n", rlp, cnx->state);
586 cnx->state |= VETH_STATE_SHUTDOWN; 808 cnx->state |= VETH_STATE_SHUTDOWN;
587 spin_unlock_irq(&cnx->lock); 809 spin_unlock_irq(&cnx->lock);
588} 810}
@@ -591,7 +813,7 @@ static int veth_init_connection(u8 rlp)
591{ 813{
592 struct veth_lpar_connection *cnx; 814 struct veth_lpar_connection *cnx;
593 struct veth_msg *msgs; 815 struct veth_msg *msgs;
594 int i; 816 int i, rc;
595 817
596 if ( (rlp == this_lp) 818 if ( (rlp == this_lp)
597 || ! HvLpConfig_doLpsCommunicateOnVirtualLan(this_lp, rlp) ) 819 || ! HvLpConfig_doLpsCommunicateOnVirtualLan(this_lp, rlp) )
@@ -605,22 +827,36 @@ static int veth_init_connection(u8 rlp)
605 cnx->remote_lp = rlp; 827 cnx->remote_lp = rlp;
606 spin_lock_init(&cnx->lock); 828 spin_lock_init(&cnx->lock);
607 INIT_WORK(&cnx->statemachine_wq, veth_statemachine, cnx); 829 INIT_WORK(&cnx->statemachine_wq, veth_statemachine, cnx);
830
608 init_timer(&cnx->ack_timer); 831 init_timer(&cnx->ack_timer);
609 cnx->ack_timer.function = veth_timed_ack; 832 cnx->ack_timer.function = veth_timed_ack;
610 cnx->ack_timer.data = (unsigned long) cnx; 833 cnx->ack_timer.data = (unsigned long) cnx;
834
835 init_timer(&cnx->reset_timer);
836 cnx->reset_timer.function = veth_timed_reset;
837 cnx->reset_timer.data = (unsigned long) cnx;
838 cnx->reset_timeout = 5 * HZ * (VETH_ACKTIMEOUT / 1000000);
839
611 memset(&cnx->pending_acks, 0xff, sizeof (cnx->pending_acks)); 840 memset(&cnx->pending_acks, 0xff, sizeof (cnx->pending_acks));
612 841
613 veth_cnx[rlp] = cnx; 842 veth_cnx[rlp] = cnx;
614 843
844 /* This gets us 1 reference, which is held on behalf of the driver
845 * infrastructure. It's released at module unload. */
846 kobject_init(&cnx->kobject);
847 cnx->kobject.ktype = &veth_lpar_connection_ktype;
848 rc = kobject_set_name(&cnx->kobject, "cnx%.2d", rlp);
849 if (rc != 0)
850 return rc;
851
615 msgs = kmalloc(VETH_NUMBUFFERS * sizeof(struct veth_msg), GFP_KERNEL); 852 msgs = kmalloc(VETH_NUMBUFFERS * sizeof(struct veth_msg), GFP_KERNEL);
616 if (! msgs) { 853 if (! msgs) {
617 veth_error("Can't allocate buffers for lpar %d\n", rlp); 854 veth_error("Can't allocate buffers for LPAR %d.\n", rlp);
618 return -ENOMEM; 855 return -ENOMEM;
619 } 856 }
620 857
621 cnx->msgs = msgs; 858 cnx->msgs = msgs;
622 memset(msgs, 0, VETH_NUMBUFFERS * sizeof(struct veth_msg)); 859 memset(msgs, 0, VETH_NUMBUFFERS * sizeof(struct veth_msg));
623 spin_lock_init(&cnx->msg_stack_lock);
624 860
625 for (i = 0; i < VETH_NUMBUFFERS; i++) { 861 for (i = 0; i < VETH_NUMBUFFERS; i++) {
626 msgs[i].token = i; 862 msgs[i].token = i;
@@ -630,8 +866,7 @@ static int veth_init_connection(u8 rlp)
630 cnx->num_events = veth_allocate_events(rlp, 2 + VETH_NUMBUFFERS); 866 cnx->num_events = veth_allocate_events(rlp, 2 + VETH_NUMBUFFERS);
631 867
632 if (cnx->num_events < (2 + VETH_NUMBUFFERS)) { 868 if (cnx->num_events < (2 + VETH_NUMBUFFERS)) {
633 veth_error("Can't allocate events for lpar %d, only got %d\n", 869 veth_error("Can't allocate enough events for LPAR %d.\n", rlp);
634 rlp, cnx->num_events);
635 return -ENOMEM; 870 return -ENOMEM;
636 } 871 }
637 872
@@ -642,11 +877,9 @@ static int veth_init_connection(u8 rlp)
642 return 0; 877 return 0;
643} 878}
644 879
645static void veth_stop_connection(u8 rlp) 880static void veth_stop_connection(struct veth_lpar_connection *cnx)
646{ 881{
647 struct veth_lpar_connection *cnx = veth_cnx[rlp]; 882 if (!cnx)
648
649 if (! cnx)
650 return; 883 return;
651 884
652 spin_lock_irq(&cnx->lock); 885 spin_lock_irq(&cnx->lock);
@@ -654,12 +887,23 @@ static void veth_stop_connection(u8 rlp)
654 veth_kick_statemachine(cnx); 887 veth_kick_statemachine(cnx);
655 spin_unlock_irq(&cnx->lock); 888 spin_unlock_irq(&cnx->lock);
656 889
890 /* There's a slim chance the reset code has just queued the
891 * statemachine to run in five seconds. If so we need to cancel
892 * that and requeue the work to run now. */
893 if (cancel_delayed_work(&cnx->statemachine_wq)) {
894 spin_lock_irq(&cnx->lock);
895 veth_kick_statemachine(cnx);
896 spin_unlock_irq(&cnx->lock);
897 }
898
899 /* Wait for the state machine to run. */
657 flush_scheduled_work(); 900 flush_scheduled_work();
901}
658 902
659 /* FIXME: not sure if this is necessary - will already have 903static void veth_destroy_connection(struct veth_lpar_connection *cnx)
660 * been deleted by the state machine, just want to make sure 904{
661 * its not running any more */ 905 if (!cnx)
662 del_timer_sync(&cnx->ack_timer); 906 return;
663 907
664 if (cnx->num_events > 0) 908 if (cnx->num_events > 0)
665 mf_deallocate_lp_events(cnx->remote_lp, 909 mf_deallocate_lp_events(cnx->remote_lp,
@@ -671,18 +915,18 @@ static void veth_stop_connection(u8 rlp)
671 HvLpEvent_Type_VirtualLan, 915 HvLpEvent_Type_VirtualLan,
672 cnx->num_ack_events, 916 cnx->num_ack_events,
673 NULL, NULL); 917 NULL, NULL);
674}
675
676static void veth_destroy_connection(u8 rlp)
677{
678 struct veth_lpar_connection *cnx = veth_cnx[rlp];
679
680 if (! cnx)
681 return;
682 918
683 kfree(cnx->msgs); 919 kfree(cnx->msgs);
920 veth_cnx[cnx->remote_lp] = NULL;
684 kfree(cnx); 921 kfree(cnx);
685 veth_cnx[rlp] = NULL; 922}
923
924static void veth_release_connection(struct kobject *kobj)
925{
926 struct veth_lpar_connection *cnx;
927 cnx = container_of(kobj, struct veth_lpar_connection, kobject);
928 veth_stop_connection(cnx);
929 veth_destroy_connection(cnx);
686} 930}
687 931
688/* 932/*
@@ -726,17 +970,15 @@ static void veth_set_multicast_list(struct net_device *dev)
726 970
727 write_lock_irqsave(&port->mcast_gate, flags); 971 write_lock_irqsave(&port->mcast_gate, flags);
728 972
729 if (dev->flags & IFF_PROMISC) { /* set promiscuous mode */ 973 if ((dev->flags & IFF_PROMISC) || (dev->flags & IFF_ALLMULTI) ||
730 printk(KERN_INFO "%s: Promiscuous mode enabled.\n", 974 (dev->mc_count > VETH_MAX_MCAST)) {
731 dev->name);
732 port->promiscuous = 1; 975 port->promiscuous = 1;
733 } else if ( (dev->flags & IFF_ALLMULTI)
734 || (dev->mc_count > VETH_MAX_MCAST) ) {
735 port->all_mcast = 1;
736 } else { 976 } else {
737 struct dev_mc_list *dmi = dev->mc_list; 977 struct dev_mc_list *dmi = dev->mc_list;
738 int i; 978 int i;
739 979
980 port->promiscuous = 0;
981
740 /* Update table */ 982 /* Update table */
741 port->num_mcast = 0; 983 port->num_mcast = 0;
742 984
@@ -758,9 +1000,10 @@ static void veth_set_multicast_list(struct net_device *dev)
758 1000
759static void veth_get_drvinfo(struct net_device *dev, struct ethtool_drvinfo *info) 1001static void veth_get_drvinfo(struct net_device *dev, struct ethtool_drvinfo *info)
760{ 1002{
761 strncpy(info->driver, "veth", sizeof(info->driver) - 1); 1003 strncpy(info->driver, DRV_NAME, sizeof(info->driver) - 1);
762 info->driver[sizeof(info->driver) - 1] = '\0'; 1004 info->driver[sizeof(info->driver) - 1] = '\0';
763 strncpy(info->version, "1.0", sizeof(info->version) - 1); 1005 strncpy(info->version, DRV_VERSION, sizeof(info->version) - 1);
1006 info->version[sizeof(info->version) - 1] = '\0';
764} 1007}
765 1008
766static int veth_get_settings(struct net_device *dev, struct ethtool_cmd *ecmd) 1009static int veth_get_settings(struct net_device *dev, struct ethtool_cmd *ecmd)
@@ -791,49 +1034,6 @@ static struct ethtool_ops ops = {
791 .get_link = veth_get_link, 1034 .get_link = veth_get_link,
792}; 1035};
793 1036
794static void veth_tx_timeout(struct net_device *dev)
795{
796 struct veth_port *port = (struct veth_port *)dev->priv;
797 struct net_device_stats *stats = &port->stats;
798 unsigned long flags;
799 int i;
800
801 stats->tx_errors++;
802
803 spin_lock_irqsave(&port->pending_gate, flags);
804
805 if (!port->pending_lpmask) {
806 spin_unlock_irqrestore(&port->pending_gate, flags);
807 return;
808 }
809
810 printk(KERN_WARNING "%s: Tx timeout! Resetting lp connections: %08x\n",
811 dev->name, port->pending_lpmask);
812
813 for (i = 0; i < HVMAXARCHITECTEDLPS; i++) {
814 struct veth_lpar_connection *cnx = veth_cnx[i];
815
816 if (! (port->pending_lpmask & (1<<i)))
817 continue;
818
819 /* If we're pending on it, we must be connected to it,
820 * so we should certainly have a structure for it. */
821 BUG_ON(! cnx);
822
823 /* Theoretically we could be kicking a connection
824 * which doesn't deserve it, but in practice if we've
825 * had a Tx timeout, the pending_lpmask will have
826 * exactly one bit set - the connection causing the
827 * problem. */
828 spin_lock(&cnx->lock);
829 cnx->state |= VETH_STATE_RESET;
830 veth_kick_statemachine(cnx);
831 spin_unlock(&cnx->lock);
832 }
833
834 spin_unlock_irqrestore(&port->pending_gate, flags);
835}
836
837static struct net_device * __init veth_probe_one(int vlan, struct device *vdev) 1037static struct net_device * __init veth_probe_one(int vlan, struct device *vdev)
838{ 1038{
839 struct net_device *dev; 1039 struct net_device *dev;
@@ -848,8 +1048,9 @@ static struct net_device * __init veth_probe_one(int vlan, struct device *vdev)
848 1048
849 port = (struct veth_port *) dev->priv; 1049 port = (struct veth_port *) dev->priv;
850 1050
851 spin_lock_init(&port->pending_gate); 1051 spin_lock_init(&port->queue_lock);
852 rwlock_init(&port->mcast_gate); 1052 rwlock_init(&port->mcast_gate);
1053 port->stopped_map = 0;
853 1054
854 for (i = 0; i < HVMAXARCHITECTEDLPS; i++) { 1055 for (i = 0; i < HVMAXARCHITECTEDLPS; i++) {
855 HvLpVirtualLanIndexMap map; 1056 HvLpVirtualLanIndexMap map;
@@ -882,22 +1083,24 @@ static struct net_device * __init veth_probe_one(int vlan, struct device *vdev)
882 dev->set_multicast_list = veth_set_multicast_list; 1083 dev->set_multicast_list = veth_set_multicast_list;
883 SET_ETHTOOL_OPS(dev, &ops); 1084 SET_ETHTOOL_OPS(dev, &ops);
884 1085
885 dev->watchdog_timeo = 2 * (VETH_ACKTIMEOUT * HZ / 1000000);
886 dev->tx_timeout = veth_tx_timeout;
887
888 SET_NETDEV_DEV(dev, vdev); 1086 SET_NETDEV_DEV(dev, vdev);
889 1087
890 rc = register_netdev(dev); 1088 rc = register_netdev(dev);
891 if (rc != 0) { 1089 if (rc != 0) {
892 veth_printk(KERN_ERR, 1090 veth_error("Failed registering net device for vlan%d.\n", vlan);
893 "Failed to register ethernet device for vlan %d\n",
894 vlan);
895 free_netdev(dev); 1091 free_netdev(dev);
896 return NULL; 1092 return NULL;
897 } 1093 }
898 1094
899 veth_printk(KERN_DEBUG, "%s attached to iSeries vlan %d (lpar_map=0x%04x)\n", 1095 kobject_init(&port->kobject);
900 dev->name, vlan, port->lpar_map); 1096 port->kobject.parent = &dev->class_dev.kobj;
1097 port->kobject.ktype = &veth_port_ktype;
1098 kobject_set_name(&port->kobject, "veth_port");
1099 if (0 != kobject_add(&port->kobject))
1100 veth_error("Failed adding port for %s to sysfs.\n", dev->name);
1101
1102 veth_info("%s attached to iSeries vlan %d (LPAR map = 0x%.4X)\n",
1103 dev->name, vlan, port->lpar_map);
901 1104
902 return dev; 1105 return dev;
903} 1106}
@@ -912,98 +1115,95 @@ static int veth_transmit_to_one(struct sk_buff *skb, HvLpIndex rlp,
912 struct veth_lpar_connection *cnx = veth_cnx[rlp]; 1115 struct veth_lpar_connection *cnx = veth_cnx[rlp];
913 struct veth_port *port = (struct veth_port *) dev->priv; 1116 struct veth_port *port = (struct veth_port *) dev->priv;
914 HvLpEvent_Rc rc; 1117 HvLpEvent_Rc rc;
915 u32 dma_address, dma_length;
916 struct veth_msg *msg = NULL; 1118 struct veth_msg *msg = NULL;
917 int err = 0;
918 unsigned long flags; 1119 unsigned long flags;
919 1120
920 if (! cnx) { 1121 if (! cnx)
921 port->stats.tx_errors++;
922 dev_kfree_skb(skb);
923 return 0; 1122 return 0;
924 }
925 1123
926 spin_lock_irqsave(&cnx->lock, flags); 1124 spin_lock_irqsave(&cnx->lock, flags);
927 1125
928 if (! (cnx->state & VETH_STATE_READY)) 1126 if (! (cnx->state & VETH_STATE_READY))
929 goto drop; 1127 goto no_error;
930 1128
931 if ((skb->len - 14) > VETH_MAX_MTU) 1129 if ((skb->len - ETH_HLEN) > VETH_MAX_MTU)
932 goto drop; 1130 goto drop;
933 1131
934 msg = veth_stack_pop(cnx); 1132 msg = veth_stack_pop(cnx);
935 1133 if (! msg)
936 if (! msg) {
937 err = 1;
938 goto drop; 1134 goto drop;
939 }
940 1135
941 dma_length = skb->len; 1136 msg->in_use = 1;
942 dma_address = dma_map_single(port->dev, skb->data, 1137 msg->skb = skb_get(skb);
943 dma_length, DMA_TO_DEVICE); 1138
1139 msg->data.addr[0] = dma_map_single(port->dev, skb->data,
1140 skb->len, DMA_TO_DEVICE);
944 1141
945 if (dma_mapping_error(dma_address)) 1142 if (dma_mapping_error(msg->data.addr[0]))
946 goto recycle_and_drop; 1143 goto recycle_and_drop;
947 1144
948 /* Is it really necessary to check the length and address
949 * fields of the first entry here? */
950 msg->skb = skb;
951 msg->dev = port->dev; 1145 msg->dev = port->dev;
952 msg->data.addr[0] = dma_address; 1146 msg->data.len[0] = skb->len;
953 msg->data.len[0] = dma_length;
954 msg->data.eofmask = 1 << VETH_EOF_SHIFT; 1147 msg->data.eofmask = 1 << VETH_EOF_SHIFT;
955 set_bit(0, &(msg->in_use)); 1148
956 rc = veth_signaldata(cnx, VethEventTypeFrames, msg->token, &msg->data); 1149 rc = veth_signaldata(cnx, VETH_EVENT_FRAMES, msg->token, &msg->data);
957 1150
958 if (rc != HvLpEvent_Rc_Good) 1151 if (rc != HvLpEvent_Rc_Good)
959 goto recycle_and_drop; 1152 goto recycle_and_drop;
960 1153
1154 /* If the timer's not already running, start it now. */
1155 if (0 == cnx->outstanding_tx)
1156 mod_timer(&cnx->reset_timer, jiffies + cnx->reset_timeout);
1157
1158 cnx->last_contact = jiffies;
1159 cnx->outstanding_tx++;
1160
1161 if (veth_stack_is_empty(cnx))
1162 veth_stop_queues(cnx);
1163
1164 no_error:
961 spin_unlock_irqrestore(&cnx->lock, flags); 1165 spin_unlock_irqrestore(&cnx->lock, flags);
962 return 0; 1166 return 0;
963 1167
964 recycle_and_drop: 1168 recycle_and_drop:
965 msg->skb = NULL;
966 /* need to set in use to make veth_recycle_msg in case this
967 * was a mapping failure */
968 set_bit(0, &msg->in_use);
969 veth_recycle_msg(cnx, msg); 1169 veth_recycle_msg(cnx, msg);
970 drop: 1170 drop:
971 port->stats.tx_errors++;
972 dev_kfree_skb(skb);
973 spin_unlock_irqrestore(&cnx->lock, flags); 1171 spin_unlock_irqrestore(&cnx->lock, flags);
974 return err; 1172 return 1;
975} 1173}
976 1174
977static HvLpIndexMap veth_transmit_to_many(struct sk_buff *skb, 1175static void veth_transmit_to_many(struct sk_buff *skb,
978 HvLpIndexMap lpmask, 1176 HvLpIndexMap lpmask,
979 struct net_device *dev) 1177 struct net_device *dev)
980{ 1178{
981 struct veth_port *port = (struct veth_port *) dev->priv; 1179 struct veth_port *port = (struct veth_port *) dev->priv;
982 int i; 1180 int i, success, error;
983 int rc; 1181
1182 success = error = 0;
984 1183
985 for (i = 0; i < HVMAXARCHITECTEDLPS; i++) { 1184 for (i = 0; i < HVMAXARCHITECTEDLPS; i++) {
986 if ((lpmask & (1 << i)) == 0) 1185 if ((lpmask & (1 << i)) == 0)
987 continue; 1186 continue;
988 1187
989 rc = veth_transmit_to_one(skb_get(skb), i, dev); 1188 if (veth_transmit_to_one(skb, i, dev))
990 if (! rc) 1189 error = 1;
991 lpmask &= ~(1<<i); 1190 else
1191 success = 1;
992 } 1192 }
993 1193
994 if (! lpmask) { 1194 if (error)
1195 port->stats.tx_errors++;
1196
1197 if (success) {
995 port->stats.tx_packets++; 1198 port->stats.tx_packets++;
996 port->stats.tx_bytes += skb->len; 1199 port->stats.tx_bytes += skb->len;
997 } 1200 }
998
999 return lpmask;
1000} 1201}
1001 1202
1002static int veth_start_xmit(struct sk_buff *skb, struct net_device *dev) 1203static int veth_start_xmit(struct sk_buff *skb, struct net_device *dev)
1003{ 1204{
1004 unsigned char *frame = skb->data; 1205 unsigned char *frame = skb->data;
1005 struct veth_port *port = (struct veth_port *) dev->priv; 1206 struct veth_port *port = (struct veth_port *) dev->priv;
1006 unsigned long flags;
1007 HvLpIndexMap lpmask; 1207 HvLpIndexMap lpmask;
1008 1208
1009 if (! (frame[0] & 0x01)) { 1209 if (! (frame[0] & 0x01)) {
@@ -1020,44 +1220,27 @@ static int veth_start_xmit(struct sk_buff *skb, struct net_device *dev)
1020 lpmask = port->lpar_map; 1220 lpmask = port->lpar_map;
1021 } 1221 }
1022 1222
1023 spin_lock_irqsave(&port->pending_gate, flags); 1223 veth_transmit_to_many(skb, lpmask, dev);
1024
1025 lpmask = veth_transmit_to_many(skb, lpmask, dev);
1026
1027 dev->trans_start = jiffies;
1028 1224
1029 if (! lpmask) { 1225 dev_kfree_skb(skb);
1030 dev_kfree_skb(skb);
1031 } else {
1032 if (port->pending_skb) {
1033 veth_error("%s: Tx while skb was pending!\n",
1034 dev->name);
1035 dev_kfree_skb(skb);
1036 spin_unlock_irqrestore(&port->pending_gate, flags);
1037 return 1;
1038 }
1039
1040 port->pending_skb = skb;
1041 port->pending_lpmask = lpmask;
1042 netif_stop_queue(dev);
1043 }
1044
1045 spin_unlock_irqrestore(&port->pending_gate, flags);
1046 1226
1047 return 0; 1227 return 0;
1048} 1228}
1049 1229
1230/* You must hold the connection's lock when you call this function. */
1050static void veth_recycle_msg(struct veth_lpar_connection *cnx, 1231static void veth_recycle_msg(struct veth_lpar_connection *cnx,
1051 struct veth_msg *msg) 1232 struct veth_msg *msg)
1052{ 1233{
1053 u32 dma_address, dma_length; 1234 u32 dma_address, dma_length;
1054 1235
1055 if (test_and_clear_bit(0, &msg->in_use)) { 1236 if (msg->in_use) {
1237 msg->in_use = 0;
1056 dma_address = msg->data.addr[0]; 1238 dma_address = msg->data.addr[0];
1057 dma_length = msg->data.len[0]; 1239 dma_length = msg->data.len[0];
1058 1240
1059 dma_unmap_single(msg->dev, dma_address, dma_length, 1241 if (!dma_mapping_error(dma_address))
1060 DMA_TO_DEVICE); 1242 dma_unmap_single(msg->dev, dma_address, dma_length,
1243 DMA_TO_DEVICE);
1061 1244
1062 if (msg->skb) { 1245 if (msg->skb) {
1063 dev_kfree_skb_any(msg->skb); 1246 dev_kfree_skb_any(msg->skb);
@@ -1066,15 +1249,16 @@ static void veth_recycle_msg(struct veth_lpar_connection *cnx,
1066 1249
1067 memset(&msg->data, 0, sizeof(msg->data)); 1250 memset(&msg->data, 0, sizeof(msg->data));
1068 veth_stack_push(cnx, msg); 1251 veth_stack_push(cnx, msg);
1069 } else 1252 } else if (cnx->state & VETH_STATE_OPEN) {
1070 if (cnx->state & VETH_STATE_OPEN) 1253 veth_error("Non-pending frame (# %d) acked by LPAR %d.\n",
1071 veth_error("Bogus frames ack from lpar %d (#%d)\n", 1254 cnx->remote_lp, msg->token);
1072 cnx->remote_lp, msg->token); 1255 }
1073} 1256}
1074 1257
1075static void veth_flush_pending(struct veth_lpar_connection *cnx) 1258static void veth_wake_queues(struct veth_lpar_connection *cnx)
1076{ 1259{
1077 int i; 1260 int i;
1261
1078 for (i = 0; i < HVMAXARCHITECTEDVIRTUALLANS; i++) { 1262 for (i = 0; i < HVMAXARCHITECTEDVIRTUALLANS; i++) {
1079 struct net_device *dev = veth_dev[i]; 1263 struct net_device *dev = veth_dev[i];
1080 struct veth_port *port; 1264 struct veth_port *port;
@@ -1088,20 +1272,77 @@ static void veth_flush_pending(struct veth_lpar_connection *cnx)
1088 if (! (port->lpar_map & (1<<cnx->remote_lp))) 1272 if (! (port->lpar_map & (1<<cnx->remote_lp)))
1089 continue; 1273 continue;
1090 1274
1091 spin_lock_irqsave(&port->pending_gate, flags); 1275 spin_lock_irqsave(&port->queue_lock, flags);
1092 if (port->pending_skb) { 1276
1093 port->pending_lpmask = 1277 port->stopped_map &= ~(1 << cnx->remote_lp);
1094 veth_transmit_to_many(port->pending_skb, 1278
1095 port->pending_lpmask, 1279 if (0 == port->stopped_map && netif_queue_stopped(dev)) {
1096 dev); 1280 veth_debug("cnx %d: woke queue for %s.\n",
1097 if (! port->pending_lpmask) { 1281 cnx->remote_lp, dev->name);
1098 dev_kfree_skb_any(port->pending_skb); 1282 netif_wake_queue(dev);
1099 port->pending_skb = NULL; 1283 }
1100 netif_wake_queue(dev); 1284 spin_unlock_irqrestore(&port->queue_lock, flags);
1101 } 1285 }
1286}
1287
1288static void veth_stop_queues(struct veth_lpar_connection *cnx)
1289{
1290 int i;
1291
1292 for (i = 0; i < HVMAXARCHITECTEDVIRTUALLANS; i++) {
1293 struct net_device *dev = veth_dev[i];
1294 struct veth_port *port;
1295
1296 if (! dev)
1297 continue;
1298
1299 port = (struct veth_port *)dev->priv;
1300
1301 /* If this cnx is not on the vlan for this port, continue */
1302 if (! (port->lpar_map & (1 << cnx->remote_lp)))
1303 continue;
1304
1305 spin_lock(&port->queue_lock);
1306
1307 netif_stop_queue(dev);
1308 port->stopped_map |= (1 << cnx->remote_lp);
1309
1310 veth_debug("cnx %d: stopped queue for %s, map = 0x%x.\n",
1311 cnx->remote_lp, dev->name, port->stopped_map);
1312
1313 spin_unlock(&port->queue_lock);
1314 }
1315}
1316
1317static void veth_timed_reset(unsigned long ptr)
1318{
1319 struct veth_lpar_connection *cnx = (struct veth_lpar_connection *)ptr;
1320 unsigned long trigger_time, flags;
1321
1322 /* FIXME is it possible this fires after veth_stop_connection()?
1323 * That would reschedule the statemachine for 5 seconds and probably
1324 * execute it after the module's been unloaded. Hmm. */
1325
1326 spin_lock_irqsave(&cnx->lock, flags);
1327
1328 if (cnx->outstanding_tx > 0) {
1329 trigger_time = cnx->last_contact + cnx->reset_timeout;
1330
1331 if (trigger_time < jiffies) {
1332 cnx->state |= VETH_STATE_RESET;
1333 veth_kick_statemachine(cnx);
1334 veth_error("%d packets not acked by LPAR %d within %d "
1335 "seconds, resetting.\n",
1336 cnx->outstanding_tx, cnx->remote_lp,
1337 cnx->reset_timeout / HZ);
1338 } else {
1339 /* Reschedule the timer */
1340 trigger_time = jiffies + cnx->reset_timeout;
1341 mod_timer(&cnx->reset_timer, trigger_time);
1102 } 1342 }
1103 spin_unlock_irqrestore(&port->pending_gate, flags);
1104 } 1343 }
1344
1345 spin_unlock_irqrestore(&cnx->lock, flags);
1105} 1346}
1106 1347
1107/* 1348/*
@@ -1117,12 +1358,9 @@ static inline int veth_frame_wanted(struct veth_port *port, u64 mac_addr)
1117 if ( (mac_addr == port->mac_addr) || (mac_addr == 0xffffffffffff0000) ) 1358 if ( (mac_addr == port->mac_addr) || (mac_addr == 0xffffffffffff0000) )
1118 return 1; 1359 return 1;
1119 1360
1120 if (! (((char *) &mac_addr)[0] & 0x01))
1121 return 0;
1122
1123 read_lock_irqsave(&port->mcast_gate, flags); 1361 read_lock_irqsave(&port->mcast_gate, flags);
1124 1362
1125 if (port->promiscuous || port->all_mcast) { 1363 if (port->promiscuous) {
1126 wanted = 1; 1364 wanted = 1;
1127 goto out; 1365 goto out;
1128 } 1366 }
@@ -1175,21 +1413,21 @@ static void veth_flush_acks(struct veth_lpar_connection *cnx)
1175{ 1413{
1176 HvLpEvent_Rc rc; 1414 HvLpEvent_Rc rc;
1177 1415
1178 rc = veth_signaldata(cnx, VethEventTypeFramesAck, 1416 rc = veth_signaldata(cnx, VETH_EVENT_FRAMES_ACK,
1179 0, &cnx->pending_acks); 1417 0, &cnx->pending_acks);
1180 1418
1181 if (rc != HvLpEvent_Rc_Good) 1419 if (rc != HvLpEvent_Rc_Good)
1182 veth_error("Error 0x%x acking frames from lpar %d!\n", 1420 veth_error("Failed acking frames from LPAR %d, rc = %d\n",
1183 (unsigned)rc, cnx->remote_lp); 1421 cnx->remote_lp, (int)rc);
1184 1422
1185 cnx->num_pending_acks = 0; 1423 cnx->num_pending_acks = 0;
1186 memset(&cnx->pending_acks, 0xff, sizeof(cnx->pending_acks)); 1424 memset(&cnx->pending_acks, 0xff, sizeof(cnx->pending_acks));
1187} 1425}
1188 1426
1189static void veth_receive(struct veth_lpar_connection *cnx, 1427static void veth_receive(struct veth_lpar_connection *cnx,
1190 struct VethLpEvent *event) 1428 struct veth_lpevent *event)
1191{ 1429{
1192 struct VethFramesData *senddata = &event->u.frames_data; 1430 struct veth_frames_data *senddata = &event->u.frames_data;
1193 int startchunk = 0; 1431 int startchunk = 0;
1194 int nchunks; 1432 int nchunks;
1195 unsigned long flags; 1433 unsigned long flags;
@@ -1216,9 +1454,10 @@ static void veth_receive(struct veth_lpar_connection *cnx,
1216 /* make sure that we have at least 1 EOF entry in the 1454 /* make sure that we have at least 1 EOF entry in the
1217 * remaining entries */ 1455 * remaining entries */
1218 if (! (senddata->eofmask >> (startchunk + VETH_EOF_SHIFT))) { 1456 if (! (senddata->eofmask >> (startchunk + VETH_EOF_SHIFT))) {
1219 veth_error("missing EOF frag in event " 1457 veth_error("Missing EOF fragment in event "
1220 "eofmask=0x%x startchunk=%d\n", 1458 "eofmask = 0x%x startchunk = %d\n",
1221 (unsigned) senddata->eofmask, startchunk); 1459 (unsigned)senddata->eofmask,
1460 startchunk);
1222 break; 1461 break;
1223 } 1462 }
1224 1463
@@ -1237,8 +1476,9 @@ static void veth_receive(struct veth_lpar_connection *cnx,
1237 /* nchunks == # of chunks in this frame */ 1476 /* nchunks == # of chunks in this frame */
1238 1477
1239 if ((length - ETH_HLEN) > VETH_MAX_MTU) { 1478 if ((length - ETH_HLEN) > VETH_MAX_MTU) {
1240 veth_error("Received oversize frame from lpar %d " 1479 veth_error("Received oversize frame from LPAR %d "
1241 "(length=%d)\n", cnx->remote_lp, length); 1480 "(length = %d)\n",
1481 cnx->remote_lp, length);
1242 continue; 1482 continue;
1243 } 1483 }
1244 1484
@@ -1331,15 +1571,33 @@ static void veth_timed_ack(unsigned long ptr)
1331 1571
1332static int veth_remove(struct vio_dev *vdev) 1572static int veth_remove(struct vio_dev *vdev)
1333{ 1573{
1334 int i = vdev->unit_address; 1574 struct veth_lpar_connection *cnx;
1335 struct net_device *dev; 1575 struct net_device *dev;
1576 struct veth_port *port;
1577 int i;
1336 1578
1337 dev = veth_dev[i]; 1579 dev = veth_dev[vdev->unit_address];
1338 if (dev != NULL) { 1580
1339 veth_dev[i] = NULL; 1581 if (! dev)
1340 unregister_netdev(dev); 1582 return 0;
1341 free_netdev(dev); 1583
1584 port = netdev_priv(dev);
1585
1586 for (i = 0; i < HVMAXARCHITECTEDLPS; i++) {
1587 cnx = veth_cnx[i];
1588
1589 if (cnx && (port->lpar_map & (1 << i))) {
1590 /* Drop our reference to connections on our VLAN */
1591 kobject_put(&cnx->kobject);
1592 }
1342 } 1593 }
1594
1595 veth_dev[vdev->unit_address] = NULL;
1596 kobject_del(&port->kobject);
1597 kobject_put(&port->kobject);
1598 unregister_netdev(dev);
1599 free_netdev(dev);
1600
1343 return 0; 1601 return 0;
1344} 1602}
1345 1603
@@ -1347,6 +1605,7 @@ static int veth_probe(struct vio_dev *vdev, const struct vio_device_id *id)
1347{ 1605{
1348 int i = vdev->unit_address; 1606 int i = vdev->unit_address;
1349 struct net_device *dev; 1607 struct net_device *dev;
1608 struct veth_port *port;
1350 1609
1351 dev = veth_probe_one(i, &vdev->dev); 1610 dev = veth_probe_one(i, &vdev->dev);
1352 if (dev == NULL) { 1611 if (dev == NULL) {
@@ -1355,11 +1614,23 @@ static int veth_probe(struct vio_dev *vdev, const struct vio_device_id *id)
1355 } 1614 }
1356 veth_dev[i] = dev; 1615 veth_dev[i] = dev;
1357 1616
1358 /* Start the state machine on each connection, to commence 1617 port = (struct veth_port*)netdev_priv(dev);
1359 * link negotiation */ 1618
1360 for (i = 0; i < HVMAXARCHITECTEDLPS; i++) 1619 /* Start the state machine on each connection on this vlan. If we're
1361 if (veth_cnx[i]) 1620 * the first dev to do so this will commence link negotiation */
1362 veth_kick_statemachine(veth_cnx[i]); 1621 for (i = 0; i < HVMAXARCHITECTEDLPS; i++) {
1622 struct veth_lpar_connection *cnx;
1623
1624 if (! (port->lpar_map & (1 << i)))
1625 continue;
1626
1627 cnx = veth_cnx[i];
1628 if (!cnx)
1629 continue;
1630
1631 kobject_get(&cnx->kobject);
1632 veth_kick_statemachine(cnx);
1633 }
1363 1634
1364 return 0; 1635 return 0;
1365} 1636}
@@ -1370,12 +1641,12 @@ static int veth_probe(struct vio_dev *vdev, const struct vio_device_id *id)
1370 */ 1641 */
1371static struct vio_device_id veth_device_table[] __devinitdata = { 1642static struct vio_device_id veth_device_table[] __devinitdata = {
1372 { "vlan", "" }, 1643 { "vlan", "" },
1373 { NULL, NULL } 1644 { "", "" }
1374}; 1645};
1375MODULE_DEVICE_TABLE(vio, veth_device_table); 1646MODULE_DEVICE_TABLE(vio, veth_device_table);
1376 1647
1377static struct vio_driver veth_driver = { 1648static struct vio_driver veth_driver = {
1378 .name = "iseries_veth", 1649 .name = DRV_NAME,
1379 .id_table = veth_device_table, 1650 .id_table = veth_device_table,
1380 .probe = veth_probe, 1651 .probe = veth_probe,
1381 .remove = veth_remove 1652 .remove = veth_remove
@@ -1388,29 +1659,29 @@ static struct vio_driver veth_driver = {
1388void __exit veth_module_cleanup(void) 1659void __exit veth_module_cleanup(void)
1389{ 1660{
1390 int i; 1661 int i;
1662 struct veth_lpar_connection *cnx;
1391 1663
1392 /* Stop the queues first to stop any new packets being sent. */ 1664 /* Disconnect our "irq" to stop events coming from the Hypervisor. */
1393 for (i = 0; i < HVMAXARCHITECTEDVIRTUALLANS; i++)
1394 if (veth_dev[i])
1395 netif_stop_queue(veth_dev[i]);
1396
1397 /* Stop the connections before we unregister the driver. This
1398 * ensures there's no skbs lying around holding the device open. */
1399 for (i = 0; i < HVMAXARCHITECTEDLPS; ++i)
1400 veth_stop_connection(i);
1401
1402 HvLpEvent_unregisterHandler(HvLpEvent_Type_VirtualLan); 1665 HvLpEvent_unregisterHandler(HvLpEvent_Type_VirtualLan);
1403 1666
1404 /* Hypervisor callbacks may have scheduled more work while we 1667 /* Make sure any work queued from Hypervisor callbacks is finished. */
1405 * were stoping connections. Now that we've disconnected from
1406 * the hypervisor make sure everything's finished. */
1407 flush_scheduled_work(); 1668 flush_scheduled_work();
1408 1669
1409 vio_unregister_driver(&veth_driver); 1670 for (i = 0; i < HVMAXARCHITECTEDLPS; ++i) {
1671 cnx = veth_cnx[i];
1672
1673 if (!cnx)
1674 continue;
1410 1675
1411 for (i = 0; i < HVMAXARCHITECTEDLPS; ++i) 1676 /* Remove the connection from sysfs */
1412 veth_destroy_connection(i); 1677 kobject_del(&cnx->kobject);
1678 /* Drop the driver's reference to the connection */
1679 kobject_put(&cnx->kobject);
1680 }
1413 1681
1682 /* Unregister the driver, which will close all the netdevs and stop
1683 * the connections when they're no longer referenced. */
1684 vio_unregister_driver(&veth_driver);
1414} 1685}
1415module_exit(veth_module_cleanup); 1686module_exit(veth_module_cleanup);
1416 1687
@@ -1423,15 +1694,37 @@ int __init veth_module_init(void)
1423 1694
1424 for (i = 0; i < HVMAXARCHITECTEDLPS; ++i) { 1695 for (i = 0; i < HVMAXARCHITECTEDLPS; ++i) {
1425 rc = veth_init_connection(i); 1696 rc = veth_init_connection(i);
1426 if (rc != 0) { 1697 if (rc != 0)
1427 veth_module_cleanup(); 1698 goto error;
1428 return rc;
1429 }
1430 } 1699 }
1431 1700
1432 HvLpEvent_registerHandler(HvLpEvent_Type_VirtualLan, 1701 HvLpEvent_registerHandler(HvLpEvent_Type_VirtualLan,
1433 &veth_handle_event); 1702 &veth_handle_event);
1434 1703
1435 return vio_register_driver(&veth_driver); 1704 rc = vio_register_driver(&veth_driver);
1705 if (rc != 0)
1706 goto error;
1707
1708 for (i = 0; i < HVMAXARCHITECTEDLPS; ++i) {
1709 struct kobject *kobj;
1710
1711 if (!veth_cnx[i])
1712 continue;
1713
1714 kobj = &veth_cnx[i]->kobject;
1715 kobj->parent = &veth_driver.driver.kobj;
1716 /* If the add failes, complain but otherwise continue */
1717 if (0 != kobject_add(kobj))
1718 veth_error("cnx %d: Failed adding to sysfs.\n", i);
1719 }
1720
1721 return 0;
1722
1723error:
1724 for (i = 0; i < HVMAXARCHITECTEDLPS; ++i) {
1725 veth_destroy_connection(veth_cnx[i]);
1726 }
1727
1728 return rc;
1436} 1729}
1437module_init(veth_module_init); 1730module_init(veth_module_init);
diff --git a/drivers/net/iseries_veth.h b/drivers/net/iseries_veth.h
deleted file mode 100644
index d9370f79b83e..000000000000
--- a/drivers/net/iseries_veth.h
+++ /dev/null
@@ -1,46 +0,0 @@
1/* File veth.h created by Kyle A. Lucke on Mon Aug 7 2000. */
2
3#ifndef _ISERIES_VETH_H
4#define _ISERIES_VETH_H
5
6#define VethEventTypeCap (0)
7#define VethEventTypeFrames (1)
8#define VethEventTypeMonitor (2)
9#define VethEventTypeFramesAck (3)
10
11#define VETH_MAX_ACKS_PER_MSG (20)
12#define VETH_MAX_FRAMES_PER_MSG (6)
13
14struct VethFramesData {
15 u32 addr[VETH_MAX_FRAMES_PER_MSG];
16 u16 len[VETH_MAX_FRAMES_PER_MSG];
17 u32 eofmask;
18};
19#define VETH_EOF_SHIFT (32-VETH_MAX_FRAMES_PER_MSG)
20
21struct VethFramesAckData {
22 u16 token[VETH_MAX_ACKS_PER_MSG];
23};
24
25struct VethCapData {
26 u8 caps_version;
27 u8 rsvd1;
28 u16 num_buffers;
29 u16 ack_threshold;
30 u16 rsvd2;
31 u32 ack_timeout;
32 u32 rsvd3;
33 u64 rsvd4[3];
34};
35
36struct VethLpEvent {
37 struct HvLpEvent base_event;
38 union {
39 struct VethCapData caps_data;
40 struct VethFramesData frames_data;
41 struct VethFramesAckData frames_ack_data;
42 } u;
43
44};
45
46#endif /* _ISERIES_VETH_H */
diff --git a/drivers/net/ppp_generic.c b/drivers/net/ppp_generic.c
index a32668e88e09..bb71638a7c44 100644
--- a/drivers/net/ppp_generic.c
+++ b/drivers/net/ppp_generic.c
@@ -1657,7 +1657,6 @@ ppp_receive_nonmp_frame(struct ppp *ppp, struct sk_buff *skb)
1657 skb->dev = ppp->dev; 1657 skb->dev = ppp->dev;
1658 skb->protocol = htons(npindex_to_ethertype[npi]); 1658 skb->protocol = htons(npindex_to_ethertype[npi]);
1659 skb->mac.raw = skb->data; 1659 skb->mac.raw = skb->data;
1660 skb->input_dev = ppp->dev;
1661 netif_rx(skb); 1660 netif_rx(skb);
1662 ppp->dev->last_rx = jiffies; 1661 ppp->dev->last_rx = jiffies;
1663 } 1662 }
diff --git a/drivers/net/pppoe.c b/drivers/net/pppoe.c
index ce1a9bf7b9a7..82f236cc3b9b 100644
--- a/drivers/net/pppoe.c
+++ b/drivers/net/pppoe.c
@@ -377,7 +377,8 @@ abort_kfree:
377 ***********************************************************************/ 377 ***********************************************************************/
378static int pppoe_rcv(struct sk_buff *skb, 378static int pppoe_rcv(struct sk_buff *skb,
379 struct net_device *dev, 379 struct net_device *dev,
380 struct packet_type *pt) 380 struct packet_type *pt,
381 struct net_device *orig_dev)
381 382
382{ 383{
383 struct pppoe_hdr *ph; 384 struct pppoe_hdr *ph;
@@ -426,7 +427,8 @@ out:
426 ***********************************************************************/ 427 ***********************************************************************/
427static int pppoe_disc_rcv(struct sk_buff *skb, 428static int pppoe_disc_rcv(struct sk_buff *skb,
428 struct net_device *dev, 429 struct net_device *dev,
429 struct packet_type *pt) 430 struct packet_type *pt,
431 struct net_device *orig_dev)
430 432
431{ 433{
432 struct pppoe_hdr *ph; 434 struct pppoe_hdr *ph;
diff --git a/drivers/net/rrunner.c b/drivers/net/rrunner.c
index 12a86f96d973..ec1a18d189a1 100644
--- a/drivers/net/rrunner.c
+++ b/drivers/net/rrunner.c
@@ -1429,6 +1429,7 @@ static int rr_start_xmit(struct sk_buff *skb, struct net_device *dev)
1429{ 1429{
1430 struct rr_private *rrpriv = netdev_priv(dev); 1430 struct rr_private *rrpriv = netdev_priv(dev);
1431 struct rr_regs __iomem *regs = rrpriv->regs; 1431 struct rr_regs __iomem *regs = rrpriv->regs;
1432 struct hippi_cb *hcb = (struct hippi_cb *) skb->cb;
1432 struct ring_ctrl *txctrl; 1433 struct ring_ctrl *txctrl;
1433 unsigned long flags; 1434 unsigned long flags;
1434 u32 index, len = skb->len; 1435 u32 index, len = skb->len;
@@ -1460,7 +1461,7 @@ static int rr_start_xmit(struct sk_buff *skb, struct net_device *dev)
1460 ifield = (u32 *)skb_push(skb, 8); 1461 ifield = (u32 *)skb_push(skb, 8);
1461 1462
1462 ifield[0] = 0; 1463 ifield[0] = 0;
1463 ifield[1] = skb->private.ifield; 1464 ifield[1] = hcb->ifield;
1464 1465
1465 /* 1466 /*
1466 * We don't need the lock before we are actually going to start 1467 * We don't need the lock before we are actually going to start
diff --git a/drivers/net/s2io.h b/drivers/net/s2io.h
index 5d9270730ca2..bc64d967f080 100644
--- a/drivers/net/s2io.h
+++ b/drivers/net/s2io.h
@@ -762,8 +762,8 @@ static inline u64 readq(void __iomem *addr)
762{ 762{
763 u64 ret = 0; 763 u64 ret = 0;
764 ret = readl(addr + 4); 764 ret = readl(addr + 4);
765 (u64) ret <<= 32; 765 ret <<= 32;
766 (u64) ret |= readl(addr); 766 ret |= readl(addr);
767 767
768 return ret; 768 return ret;
769} 769}
diff --git a/drivers/net/shaper.c b/drivers/net/shaper.c
index 3ad0b6751f6f..221354eea21f 100644
--- a/drivers/net/shaper.c
+++ b/drivers/net/shaper.c
@@ -156,52 +156,6 @@ static int shaper_start_xmit(struct sk_buff *skb, struct net_device *dev)
156 156
157 SHAPERCB(skb)->shapelen= shaper_clocks(shaper,skb); 157 SHAPERCB(skb)->shapelen= shaper_clocks(shaper,skb);
158 158
159#ifdef SHAPER_COMPLEX /* and broken.. */
160
161 while(ptr && ptr!=(struct sk_buff *)&shaper->sendq)
162 {
163 if(ptr->pri<skb->pri
164 && jiffies - SHAPERCB(ptr)->shapeclock < SHAPER_MAXSLIP)
165 {
166 struct sk_buff *tmp=ptr->prev;
167
168 /*
169 * It goes before us therefore we slip the length
170 * of the new frame.
171 */
172
173 SHAPERCB(ptr)->shapeclock+=SHAPERCB(skb)->shapelen;
174 SHAPERCB(ptr)->shapelatency+=SHAPERCB(skb)->shapelen;
175
176 /*
177 * The packet may have slipped so far back it
178 * fell off.
179 */
180 if(SHAPERCB(ptr)->shapelatency > SHAPER_LATENCY)
181 {
182 skb_unlink(ptr);
183 dev_kfree_skb(ptr);
184 }
185 ptr=tmp;
186 }
187 else
188 break;
189 }
190 if(ptr==NULL || ptr==(struct sk_buff *)&shaper->sendq)
191 skb_queue_head(&shaper->sendq,skb);
192 else
193 {
194 struct sk_buff *tmp;
195 /*
196 * Set the packet clock out time according to the
197 * frames ahead. Im sure a bit of thought could drop
198 * this loop.
199 */
200 for(tmp=skb_peek(&shaper->sendq); tmp!=NULL && tmp!=ptr; tmp=tmp->next)
201 SHAPERCB(skb)->shapeclock+=tmp->shapelen;
202 skb_append(ptr,skb);
203 }
204#else
205 { 159 {
206 struct sk_buff *tmp; 160 struct sk_buff *tmp;
207 /* 161 /*
@@ -220,7 +174,7 @@ static int shaper_start_xmit(struct sk_buff *skb, struct net_device *dev)
220 } else 174 } else
221 skb_queue_tail(&shaper->sendq, skb); 175 skb_queue_tail(&shaper->sendq, skb);
222 } 176 }
223#endif 177
224 if(sh_debug) 178 if(sh_debug)
225 printk("Frame queued.\n"); 179 printk("Frame queued.\n");
226 if(skb_queue_len(&shaper->sendq)>SHAPER_QLEN) 180 if(skb_queue_len(&shaper->sendq)>SHAPER_QLEN)
@@ -302,7 +256,7 @@ static void shaper_kick(struct shaper *shaper)
302 * Pull the frame and get interrupts back on. 256 * Pull the frame and get interrupts back on.
303 */ 257 */
304 258
305 skb_unlink(skb); 259 skb_unlink(skb, &shaper->sendq);
306 if (shaper->recovery < 260 if (shaper->recovery <
307 SHAPERCB(skb)->shapeclock + SHAPERCB(skb)->shapelen) 261 SHAPERCB(skb)->shapeclock + SHAPERCB(skb)->shapelen)
308 shaper->recovery = SHAPERCB(skb)->shapeclock + SHAPERCB(skb)->shapelen; 262 shaper->recovery = SHAPERCB(skb)->shapeclock + SHAPERCB(skb)->shapelen;
diff --git a/drivers/net/sis190.c b/drivers/net/sis190.c
new file mode 100644
index 000000000000..bf3440aa6c24
--- /dev/null
+++ b/drivers/net/sis190.c
@@ -0,0 +1,1843 @@
1/*
2 sis190.c: Silicon Integrated Systems SiS190 ethernet driver
3
4 Copyright (c) 2003 K.M. Liu <kmliu@sis.com>
5 Copyright (c) 2003, 2004 Jeff Garzik <jgarzik@pobox.com>
6 Copyright (c) 2003, 2004, 2005 Francois Romieu <romieu@fr.zoreil.com>
7
8 Based on r8169.c, tg3.c, 8139cp.c, skge.c, epic100.c and SiS 190/191
9 genuine driver.
10
11 This software may be used and distributed according to the terms of
12 the GNU General Public License (GPL), incorporated herein by reference.
13 Drivers based on or derived from this code fall under the GPL and must
14 retain the authorship, copyright and license notice. This file is not
15 a complete program and may only be used when the entire operating
16 system is licensed under the GPL.
17
18 See the file COPYING in this distribution for more information.
19
20 */
21
22#include <linux/module.h>
23#include <linux/moduleparam.h>
24#include <linux/netdevice.h>
25#include <linux/rtnetlink.h>
26#include <linux/etherdevice.h>
27#include <linux/ethtool.h>
28#include <linux/pci.h>
29#include <linux/mii.h>
30#include <linux/delay.h>
31#include <linux/crc32.h>
32#include <linux/dma-mapping.h>
33#include <asm/irq.h>
34
35#define net_drv(p, arg...) if (netif_msg_drv(p)) \
36 printk(arg)
37#define net_probe(p, arg...) if (netif_msg_probe(p)) \
38 printk(arg)
39#define net_link(p, arg...) if (netif_msg_link(p)) \
40 printk(arg)
41#define net_intr(p, arg...) if (netif_msg_intr(p)) \
42 printk(arg)
43#define net_tx_err(p, arg...) if (netif_msg_tx_err(p)) \
44 printk(arg)
45
46#define PHY_MAX_ADDR 32
47#define PHY_ID_ANY 0x1f
48#define MII_REG_ANY 0x1f
49
50#ifdef CONFIG_SIS190_NAPI
51#define NAPI_SUFFIX "-NAPI"
52#else
53#define NAPI_SUFFIX ""
54#endif
55
56#define DRV_VERSION "1.2" NAPI_SUFFIX
57#define DRV_NAME "sis190"
58#define SIS190_DRIVER_NAME DRV_NAME " Gigabit Ethernet driver " DRV_VERSION
59#define PFX DRV_NAME ": "
60
61#ifdef CONFIG_SIS190_NAPI
62#define sis190_rx_skb netif_receive_skb
63#define sis190_rx_quota(count, quota) min(count, quota)
64#else
65#define sis190_rx_skb netif_rx
66#define sis190_rx_quota(count, quota) count
67#endif
68
69#define MAC_ADDR_LEN 6
70
71#define NUM_TX_DESC 64 /* [8..1024] */
72#define NUM_RX_DESC 64 /* [8..8192] */
73#define TX_RING_BYTES (NUM_TX_DESC * sizeof(struct TxDesc))
74#define RX_RING_BYTES (NUM_RX_DESC * sizeof(struct RxDesc))
75#define RX_BUF_SIZE 1536
76#define RX_BUF_MASK 0xfff8
77
78#define SIS190_REGS_SIZE 0x80
79#define SIS190_TX_TIMEOUT (6*HZ)
80#define SIS190_PHY_TIMEOUT (10*HZ)
81#define SIS190_MSG_DEFAULT (NETIF_MSG_DRV | NETIF_MSG_PROBE | \
82 NETIF_MSG_LINK | NETIF_MSG_IFUP | \
83 NETIF_MSG_IFDOWN)
84
85/* Enhanced PHY access register bit definitions */
86#define EhnMIIread 0x0000
87#define EhnMIIwrite 0x0020
88#define EhnMIIdataShift 16
89#define EhnMIIpmdShift 6 /* 7016 only */
90#define EhnMIIregShift 11
91#define EhnMIIreq 0x0010
92#define EhnMIInotDone 0x0010
93
94/* Write/read MMIO register */
95#define SIS_W8(reg, val) writeb ((val), ioaddr + (reg))
96#define SIS_W16(reg, val) writew ((val), ioaddr + (reg))
97#define SIS_W32(reg, val) writel ((val), ioaddr + (reg))
98#define SIS_R8(reg) readb (ioaddr + (reg))
99#define SIS_R16(reg) readw (ioaddr + (reg))
100#define SIS_R32(reg) readl (ioaddr + (reg))
101
102#define SIS_PCI_COMMIT() SIS_R32(IntrControl)
103
104enum sis190_registers {
105 TxControl = 0x00,
106 TxDescStartAddr = 0x04,
107 rsv0 = 0x08, // reserved
108 TxSts = 0x0c, // unused (Control/Status)
109 RxControl = 0x10,
110 RxDescStartAddr = 0x14,
111 rsv1 = 0x18, // reserved
112 RxSts = 0x1c, // unused
113 IntrStatus = 0x20,
114 IntrMask = 0x24,
115 IntrControl = 0x28,
116 IntrTimer = 0x2c, // unused (Interupt Timer)
117 PMControl = 0x30, // unused (Power Mgmt Control/Status)
118 rsv2 = 0x34, // reserved
119 ROMControl = 0x38,
120 ROMInterface = 0x3c,
121 StationControl = 0x40,
122 GMIIControl = 0x44,
123 GIoCR = 0x48, // unused (GMAC IO Compensation)
124 GIoCtrl = 0x4c, // unused (GMAC IO Control)
125 TxMacControl = 0x50,
126 TxLimit = 0x54, // unused (Tx MAC Timer/TryLimit)
127 RGDelay = 0x58, // unused (RGMII Tx Internal Delay)
128 rsv3 = 0x5c, // reserved
129 RxMacControl = 0x60,
130 RxMacAddr = 0x62,
131 RxHashTable = 0x68,
132 // Undocumented = 0x6c,
133 RxWolCtrl = 0x70,
134 RxWolData = 0x74, // unused (Rx WOL Data Access)
135 RxMPSControl = 0x78, // unused (Rx MPS Control)
136 rsv4 = 0x7c, // reserved
137};
138
139enum sis190_register_content {
140 /* IntrStatus */
141 SoftInt = 0x40000000, // unused
142 Timeup = 0x20000000, // unused
143 PauseFrame = 0x00080000, // unused
144 MagicPacket = 0x00040000, // unused
145 WakeupFrame = 0x00020000, // unused
146 LinkChange = 0x00010000,
147 RxQEmpty = 0x00000080,
148 RxQInt = 0x00000040,
149 TxQ1Empty = 0x00000020, // unused
150 TxQ1Int = 0x00000010,
151 TxQ0Empty = 0x00000008, // unused
152 TxQ0Int = 0x00000004,
153 RxHalt = 0x00000002,
154 TxHalt = 0x00000001,
155
156 /* {Rx/Tx}CmdBits */
157 CmdReset = 0x10,
158 CmdRxEnb = 0x08, // unused
159 CmdTxEnb = 0x01,
160 RxBufEmpty = 0x01, // unused
161
162 /* Cfg9346Bits */
163 Cfg9346_Lock = 0x00, // unused
164 Cfg9346_Unlock = 0xc0, // unused
165
166 /* RxMacControl */
167 AcceptErr = 0x20, // unused
168 AcceptRunt = 0x10, // unused
169 AcceptBroadcast = 0x0800,
170 AcceptMulticast = 0x0400,
171 AcceptMyPhys = 0x0200,
172 AcceptAllPhys = 0x0100,
173
174 /* RxConfigBits */
175 RxCfgFIFOShift = 13,
176 RxCfgDMAShift = 8, // 0x1a in RxControl ?
177
178 /* TxConfigBits */
179 TxInterFrameGapShift = 24,
180 TxDMAShift = 8, /* DMA burst value (0-7) is shift this many bits */
181
182 /* StationControl */
183 _1000bpsF = 0x1c00,
184 _1000bpsH = 0x0c00,
185 _100bpsF = 0x1800,
186 _100bpsH = 0x0800,
187 _10bpsF = 0x1400,
188 _10bpsH = 0x0400,
189
190 LinkStatus = 0x02, // unused
191 FullDup = 0x01, // unused
192
193 /* TBICSRBit */
194 TBILinkOK = 0x02000000, // unused
195};
196
197struct TxDesc {
198 __le32 PSize;
199 __le32 status;
200 __le32 addr;
201 __le32 size;
202};
203
204struct RxDesc {
205 __le32 PSize;
206 __le32 status;
207 __le32 addr;
208 __le32 size;
209};
210
211enum _DescStatusBit {
212 /* _Desc.status */
213 OWNbit = 0x80000000, // RXOWN/TXOWN
214 INTbit = 0x40000000, // RXINT/TXINT
215 CRCbit = 0x00020000, // CRCOFF/CRCEN
216 PADbit = 0x00010000, // PREADD/PADEN
217 /* _Desc.size */
218 RingEnd = 0x80000000,
219 /* TxDesc.status */
220 LSEN = 0x08000000, // TSO ? -- FR
221 IPCS = 0x04000000,
222 TCPCS = 0x02000000,
223 UDPCS = 0x01000000,
224 BSTEN = 0x00800000,
225 EXTEN = 0x00400000,
226 DEFEN = 0x00200000,
227 BKFEN = 0x00100000,
228 CRSEN = 0x00080000,
229 COLEN = 0x00040000,
230 THOL3 = 0x30000000,
231 THOL2 = 0x20000000,
232 THOL1 = 0x10000000,
233 THOL0 = 0x00000000,
234 /* RxDesc.status */
235 IPON = 0x20000000,
236 TCPON = 0x10000000,
237 UDPON = 0x08000000,
238 Wakup = 0x00400000,
239 Magic = 0x00200000,
240 Pause = 0x00100000,
241 DEFbit = 0x00200000,
242 BCAST = 0x000c0000,
243 MCAST = 0x00080000,
244 UCAST = 0x00040000,
245 /* RxDesc.PSize */
246 TAGON = 0x80000000,
247 RxDescCountMask = 0x7f000000, // multi-desc pkt when > 1 ? -- FR
248 ABORT = 0x00800000,
249 SHORT = 0x00400000,
250 LIMIT = 0x00200000,
251 MIIER = 0x00100000,
252 OVRUN = 0x00080000,
253 NIBON = 0x00040000,
254 COLON = 0x00020000,
255 CRCOK = 0x00010000,
256 RxSizeMask = 0x0000ffff
257 /*
258 * The asic could apparently do vlan, TSO, jumbo (sis191 only) and
259 * provide two (unused with Linux) Tx queues. No publically
260 * available documentation alas.
261 */
262};
263
264enum sis190_eeprom_access_register_bits {
265 EECS = 0x00000001, // unused
266 EECLK = 0x00000002, // unused
267 EEDO = 0x00000008, // unused
268 EEDI = 0x00000004, // unused
269 EEREQ = 0x00000080,
270 EEROP = 0x00000200,
271 EEWOP = 0x00000100 // unused
272};
273
274/* EEPROM Addresses */
275enum sis190_eeprom_address {
276 EEPROMSignature = 0x00,
277 EEPROMCLK = 0x01, // unused
278 EEPROMInfo = 0x02,
279 EEPROMMACAddr = 0x03
280};
281
282struct sis190_private {
283 void __iomem *mmio_addr;
284 struct pci_dev *pci_dev;
285 struct net_device_stats stats;
286 spinlock_t lock;
287 u32 rx_buf_sz;
288 u32 cur_rx;
289 u32 cur_tx;
290 u32 dirty_rx;
291 u32 dirty_tx;
292 dma_addr_t rx_dma;
293 dma_addr_t tx_dma;
294 struct RxDesc *RxDescRing;
295 struct TxDesc *TxDescRing;
296 struct sk_buff *Rx_skbuff[NUM_RX_DESC];
297 struct sk_buff *Tx_skbuff[NUM_TX_DESC];
298 struct work_struct phy_task;
299 struct timer_list timer;
300 u32 msg_enable;
301 struct mii_if_info mii_if;
302 struct list_head first_phy;
303};
304
305struct sis190_phy {
306 struct list_head list;
307 int phy_id;
308 u16 id[2];
309 u16 status;
310 u8 type;
311};
312
313enum sis190_phy_type {
314 UNKNOWN = 0x00,
315 HOME = 0x01,
316 LAN = 0x02,
317 MIX = 0x03
318};
319
320static struct mii_chip_info {
321 const char *name;
322 u16 id[2];
323 unsigned int type;
324} mii_chip_table[] = {
325 { "Broadcom PHY BCM5461", { 0x0020, 0x60c0 }, LAN },
326 { "Agere PHY ET1101B", { 0x0282, 0xf010 }, LAN },
327 { "Marvell PHY 88E1111", { 0x0141, 0x0cc0 }, LAN },
328 { "Realtek PHY RTL8201", { 0x0000, 0x8200 }, LAN },
329 { NULL, }
330};
331
332const static struct {
333 const char *name;
334 u8 version; /* depend on docs */
335 u32 RxConfigMask; /* clear the bits supported by this chip */
336} sis_chip_info[] = {
337 { DRV_NAME, 0x00, 0xff7e1880, },
338};
339
340static struct pci_device_id sis190_pci_tbl[] __devinitdata = {
341 { PCI_DEVICE(PCI_VENDOR_ID_SI, 0x0190), 0, 0, 0 },
342 { 0, },
343};
344
345MODULE_DEVICE_TABLE(pci, sis190_pci_tbl);
346
347static int rx_copybreak = 200;
348
349static struct {
350 u32 msg_enable;
351} debug = { -1 };
352
353MODULE_DESCRIPTION("SiS sis190 Gigabit Ethernet driver");
354module_param(rx_copybreak, int, 0);
355MODULE_PARM_DESC(rx_copybreak, "Copy breakpoint for copy-only-tiny-frames");
356module_param_named(debug, debug.msg_enable, int, 0);
357MODULE_PARM_DESC(debug, "Debug verbosity level (0=none, ..., 16=all)");
358MODULE_AUTHOR("K.M. Liu <kmliu@sis.com>, Ueimor <romieu@fr.zoreil.com>");
359MODULE_VERSION(DRV_VERSION);
360MODULE_LICENSE("GPL");
361
362static const u32 sis190_intr_mask =
363 RxQEmpty | RxQInt | TxQ1Int | TxQ0Int | RxHalt | TxHalt;
364
365/*
366 * Maximum number of multicast addresses to filter (vs. Rx-all-multicast).
367 * The chips use a 64 element hash table based on the Ethernet CRC.
368 */
369static int multicast_filter_limit = 32;
370
371static void __mdio_cmd(void __iomem *ioaddr, u32 ctl)
372{
373 unsigned int i;
374
375 SIS_W32(GMIIControl, ctl);
376
377 msleep(1);
378
379 for (i = 0; i < 100; i++) {
380 if (!(SIS_R32(GMIIControl) & EhnMIInotDone))
381 break;
382 msleep(1);
383 }
384
385 if (i > 999)
386 printk(KERN_ERR PFX "PHY command failed !\n");
387}
388
389static void mdio_write(void __iomem *ioaddr, int phy_id, int reg, int val)
390{
391 __mdio_cmd(ioaddr, EhnMIIreq | EhnMIIwrite |
392 (((u32) reg) << EhnMIIregShift) | (phy_id << EhnMIIpmdShift) |
393 (((u32) val) << EhnMIIdataShift));
394}
395
396static int mdio_read(void __iomem *ioaddr, int phy_id, int reg)
397{
398 __mdio_cmd(ioaddr, EhnMIIreq | EhnMIIread |
399 (((u32) reg) << EhnMIIregShift) | (phy_id << EhnMIIpmdShift));
400
401 return (u16) (SIS_R32(GMIIControl) >> EhnMIIdataShift);
402}
403
404static void __mdio_write(struct net_device *dev, int phy_id, int reg, int val)
405{
406 struct sis190_private *tp = netdev_priv(dev);
407
408 mdio_write(tp->mmio_addr, phy_id, reg, val);
409}
410
411static int __mdio_read(struct net_device *dev, int phy_id, int reg)
412{
413 struct sis190_private *tp = netdev_priv(dev);
414
415 return mdio_read(tp->mmio_addr, phy_id, reg);
416}
417
418static u16 mdio_read_latched(void __iomem *ioaddr, int phy_id, int reg)
419{
420 mdio_read(ioaddr, phy_id, reg);
421 return mdio_read(ioaddr, phy_id, reg);
422}
423
424static u16 __devinit sis190_read_eeprom(void __iomem *ioaddr, u32 reg)
425{
426 u16 data = 0xffff;
427 unsigned int i;
428
429 if (!(SIS_R32(ROMControl) & 0x0002))
430 return 0;
431
432 SIS_W32(ROMInterface, EEREQ | EEROP | (reg << 10));
433
434 for (i = 0; i < 200; i++) {
435 if (!(SIS_R32(ROMInterface) & EEREQ)) {
436 data = (SIS_R32(ROMInterface) & 0xffff0000) >> 16;
437 break;
438 }
439 msleep(1);
440 }
441
442 return data;
443}
444
445static void sis190_irq_mask_and_ack(void __iomem *ioaddr)
446{
447 SIS_W32(IntrMask, 0x00);
448 SIS_W32(IntrStatus, 0xffffffff);
449 SIS_PCI_COMMIT();
450}
451
452static void sis190_asic_down(void __iomem *ioaddr)
453{
454 /* Stop the chip's Tx and Rx DMA processes. */
455
456 SIS_W32(TxControl, 0x1a00);
457 SIS_W32(RxControl, 0x1a00);
458
459 sis190_irq_mask_and_ack(ioaddr);
460}
461
462static void sis190_mark_as_last_descriptor(struct RxDesc *desc)
463{
464 desc->size |= cpu_to_le32(RingEnd);
465}
466
467static inline void sis190_give_to_asic(struct RxDesc *desc, u32 rx_buf_sz)
468{
469 u32 eor = le32_to_cpu(desc->size) & RingEnd;
470
471 desc->PSize = 0x0;
472 desc->size = cpu_to_le32((rx_buf_sz & RX_BUF_MASK) | eor);
473 wmb();
474 desc->status = cpu_to_le32(OWNbit | INTbit);
475}
476
477static inline void sis190_map_to_asic(struct RxDesc *desc, dma_addr_t mapping,
478 u32 rx_buf_sz)
479{
480 desc->addr = cpu_to_le32(mapping);
481 sis190_give_to_asic(desc, rx_buf_sz);
482}
483
484static inline void sis190_make_unusable_by_asic(struct RxDesc *desc)
485{
486 desc->PSize = 0x0;
487 desc->addr = 0xdeadbeef;
488 desc->size &= cpu_to_le32(RingEnd);
489 wmb();
490 desc->status = 0x0;
491}
492
493static int sis190_alloc_rx_skb(struct pci_dev *pdev, struct sk_buff **sk_buff,
494 struct RxDesc *desc, u32 rx_buf_sz)
495{
496 struct sk_buff *skb;
497 dma_addr_t mapping;
498 int ret = 0;
499
500 skb = dev_alloc_skb(rx_buf_sz);
501 if (!skb)
502 goto err_out;
503
504 *sk_buff = skb;
505
506 mapping = pci_map_single(pdev, skb->data, rx_buf_sz,
507 PCI_DMA_FROMDEVICE);
508
509 sis190_map_to_asic(desc, mapping, rx_buf_sz);
510out:
511 return ret;
512
513err_out:
514 ret = -ENOMEM;
515 sis190_make_unusable_by_asic(desc);
516 goto out;
517}
518
519static u32 sis190_rx_fill(struct sis190_private *tp, struct net_device *dev,
520 u32 start, u32 end)
521{
522 u32 cur;
523
524 for (cur = start; cur < end; cur++) {
525 int ret, i = cur % NUM_RX_DESC;
526
527 if (tp->Rx_skbuff[i])
528 continue;
529
530 ret = sis190_alloc_rx_skb(tp->pci_dev, tp->Rx_skbuff + i,
531 tp->RxDescRing + i, tp->rx_buf_sz);
532 if (ret < 0)
533 break;
534 }
535 return cur - start;
536}
537
538static inline int sis190_try_rx_copy(struct sk_buff **sk_buff, int pkt_size,
539 struct RxDesc *desc, int rx_buf_sz)
540{
541 int ret = -1;
542
543 if (pkt_size < rx_copybreak) {
544 struct sk_buff *skb;
545
546 skb = dev_alloc_skb(pkt_size + NET_IP_ALIGN);
547 if (skb) {
548 skb_reserve(skb, NET_IP_ALIGN);
549 eth_copy_and_sum(skb, sk_buff[0]->data, pkt_size, 0);
550 *sk_buff = skb;
551 sis190_give_to_asic(desc, rx_buf_sz);
552 ret = 0;
553 }
554 }
555 return ret;
556}
557
558static inline int sis190_rx_pkt_err(u32 status, struct net_device_stats *stats)
559{
560#define ErrMask (OVRUN | SHORT | LIMIT | MIIER | NIBON | COLON | ABORT)
561
562 if ((status & CRCOK) && !(status & ErrMask))
563 return 0;
564
565 if (!(status & CRCOK))
566 stats->rx_crc_errors++;
567 else if (status & OVRUN)
568 stats->rx_over_errors++;
569 else if (status & (SHORT | LIMIT))
570 stats->rx_length_errors++;
571 else if (status & (MIIER | NIBON | COLON))
572 stats->rx_frame_errors++;
573
574 stats->rx_errors++;
575 return -1;
576}
577
578static int sis190_rx_interrupt(struct net_device *dev,
579 struct sis190_private *tp, void __iomem *ioaddr)
580{
581 struct net_device_stats *stats = &tp->stats;
582 u32 rx_left, cur_rx = tp->cur_rx;
583 u32 delta, count;
584
585 rx_left = NUM_RX_DESC + tp->dirty_rx - cur_rx;
586 rx_left = sis190_rx_quota(rx_left, (u32) dev->quota);
587
588 for (; rx_left > 0; rx_left--, cur_rx++) {
589 unsigned int entry = cur_rx % NUM_RX_DESC;
590 struct RxDesc *desc = tp->RxDescRing + entry;
591 u32 status;
592
593 if (desc->status & OWNbit)
594 break;
595
596 status = le32_to_cpu(desc->PSize);
597
598 // net_intr(tp, KERN_INFO "%s: Rx PSize = %08x.\n", dev->name,
599 // status);
600
601 if (sis190_rx_pkt_err(status, stats) < 0)
602 sis190_give_to_asic(desc, tp->rx_buf_sz);
603 else {
604 struct sk_buff *skb = tp->Rx_skbuff[entry];
605 int pkt_size = (status & RxSizeMask) - 4;
606 void (*pci_action)(struct pci_dev *, dma_addr_t,
607 size_t, int) = pci_dma_sync_single_for_device;
608
609 if (unlikely(pkt_size > tp->rx_buf_sz)) {
610 net_intr(tp, KERN_INFO
611 "%s: (frag) status = %08x.\n",
612 dev->name, status);
613 stats->rx_dropped++;
614 stats->rx_length_errors++;
615 sis190_give_to_asic(desc, tp->rx_buf_sz);
616 continue;
617 }
618
619 pci_dma_sync_single_for_cpu(tp->pci_dev,
620 le32_to_cpu(desc->addr), tp->rx_buf_sz,
621 PCI_DMA_FROMDEVICE);
622
623 if (sis190_try_rx_copy(&skb, pkt_size, desc,
624 tp->rx_buf_sz)) {
625 pci_action = pci_unmap_single;
626 tp->Rx_skbuff[entry] = NULL;
627 sis190_make_unusable_by_asic(desc);
628 }
629
630 pci_action(tp->pci_dev, le32_to_cpu(desc->addr),
631 tp->rx_buf_sz, PCI_DMA_FROMDEVICE);
632
633 skb->dev = dev;
634 skb_put(skb, pkt_size);
635 skb->protocol = eth_type_trans(skb, dev);
636
637 sis190_rx_skb(skb);
638
639 dev->last_rx = jiffies;
640 stats->rx_packets++;
641 stats->rx_bytes += pkt_size;
642 if ((status & BCAST) == MCAST)
643 stats->multicast++;
644 }
645 }
646 count = cur_rx - tp->cur_rx;
647 tp->cur_rx = cur_rx;
648
649 delta = sis190_rx_fill(tp, dev, tp->dirty_rx, tp->cur_rx);
650 if (!delta && count && netif_msg_intr(tp))
651 printk(KERN_INFO "%s: no Rx buffer allocated.\n", dev->name);
652 tp->dirty_rx += delta;
653
654 if (((tp->dirty_rx + NUM_RX_DESC) == tp->cur_rx) && netif_msg_intr(tp))
655 printk(KERN_EMERG "%s: Rx buffers exhausted.\n", dev->name);
656
657 return count;
658}
659
660static void sis190_unmap_tx_skb(struct pci_dev *pdev, struct sk_buff *skb,
661 struct TxDesc *desc)
662{
663 unsigned int len;
664
665 len = skb->len < ETH_ZLEN ? ETH_ZLEN : skb->len;
666
667 pci_unmap_single(pdev, le32_to_cpu(desc->addr), len, PCI_DMA_TODEVICE);
668
669 memset(desc, 0x00, sizeof(*desc));
670}
671
672static void sis190_tx_interrupt(struct net_device *dev,
673 struct sis190_private *tp, void __iomem *ioaddr)
674{
675 u32 pending, dirty_tx = tp->dirty_tx;
676 /*
677 * It would not be needed if queueing was allowed to be enabled
678 * again too early (hint: think preempt and unclocked smp systems).
679 */
680 unsigned int queue_stopped;
681
682 smp_rmb();
683 pending = tp->cur_tx - dirty_tx;
684 queue_stopped = (pending == NUM_TX_DESC);
685
686 for (; pending; pending--, dirty_tx++) {
687 unsigned int entry = dirty_tx % NUM_TX_DESC;
688 struct TxDesc *txd = tp->TxDescRing + entry;
689 struct sk_buff *skb;
690
691 if (le32_to_cpu(txd->status) & OWNbit)
692 break;
693
694 skb = tp->Tx_skbuff[entry];
695
696 tp->stats.tx_packets++;
697 tp->stats.tx_bytes += skb->len;
698
699 sis190_unmap_tx_skb(tp->pci_dev, skb, txd);
700 tp->Tx_skbuff[entry] = NULL;
701 dev_kfree_skb_irq(skb);
702 }
703
704 if (tp->dirty_tx != dirty_tx) {
705 tp->dirty_tx = dirty_tx;
706 smp_wmb();
707 if (queue_stopped)
708 netif_wake_queue(dev);
709 }
710}
711
712/*
713 * The interrupt handler does all of the Rx thread work and cleans up after
714 * the Tx thread.
715 */
716static irqreturn_t sis190_interrupt(int irq, void *__dev, struct pt_regs *regs)
717{
718 struct net_device *dev = __dev;
719 struct sis190_private *tp = netdev_priv(dev);
720 void __iomem *ioaddr = tp->mmio_addr;
721 unsigned int handled = 0;
722 u32 status;
723
724 status = SIS_R32(IntrStatus);
725
726 if ((status == 0xffffffff) || !status)
727 goto out;
728
729 handled = 1;
730
731 if (unlikely(!netif_running(dev))) {
732 sis190_asic_down(ioaddr);
733 goto out;
734 }
735
736 SIS_W32(IntrStatus, status);
737
738 // net_intr(tp, KERN_INFO "%s: status = %08x.\n", dev->name, status);
739
740 if (status & LinkChange) {
741 net_intr(tp, KERN_INFO "%s: link change.\n", dev->name);
742 schedule_work(&tp->phy_task);
743 }
744
745 if (status & RxQInt)
746 sis190_rx_interrupt(dev, tp, ioaddr);
747
748 if (status & TxQ0Int)
749 sis190_tx_interrupt(dev, tp, ioaddr);
750out:
751 return IRQ_RETVAL(handled);
752}
753
754#ifdef CONFIG_NET_POLL_CONTROLLER
755static void sis190_netpoll(struct net_device *dev)
756{
757 struct sis190_private *tp = netdev_priv(dev);
758 struct pci_dev *pdev = tp->pci_dev;
759
760 disable_irq(pdev->irq);
761 sis190_interrupt(pdev->irq, dev, NULL);
762 enable_irq(pdev->irq);
763}
764#endif
765
766static void sis190_free_rx_skb(struct sis190_private *tp,
767 struct sk_buff **sk_buff, struct RxDesc *desc)
768{
769 struct pci_dev *pdev = tp->pci_dev;
770
771 pci_unmap_single(pdev, le32_to_cpu(desc->addr), tp->rx_buf_sz,
772 PCI_DMA_FROMDEVICE);
773 dev_kfree_skb(*sk_buff);
774 *sk_buff = NULL;
775 sis190_make_unusable_by_asic(desc);
776}
777
778static void sis190_rx_clear(struct sis190_private *tp)
779{
780 unsigned int i;
781
782 for (i = 0; i < NUM_RX_DESC; i++) {
783 if (!tp->Rx_skbuff[i])
784 continue;
785 sis190_free_rx_skb(tp, tp->Rx_skbuff + i, tp->RxDescRing + i);
786 }
787}
788
789static void sis190_init_ring_indexes(struct sis190_private *tp)
790{
791 tp->dirty_tx = tp->dirty_rx = tp->cur_tx = tp->cur_rx = 0;
792}
793
794static int sis190_init_ring(struct net_device *dev)
795{
796 struct sis190_private *tp = netdev_priv(dev);
797
798 sis190_init_ring_indexes(tp);
799
800 memset(tp->Tx_skbuff, 0x0, NUM_TX_DESC * sizeof(struct sk_buff *));
801 memset(tp->Rx_skbuff, 0x0, NUM_RX_DESC * sizeof(struct sk_buff *));
802
803 if (sis190_rx_fill(tp, dev, 0, NUM_RX_DESC) != NUM_RX_DESC)
804 goto err_rx_clear;
805
806 sis190_mark_as_last_descriptor(tp->RxDescRing + NUM_RX_DESC - 1);
807
808 return 0;
809
810err_rx_clear:
811 sis190_rx_clear(tp);
812 return -ENOMEM;
813}
814
815static void sis190_set_rx_mode(struct net_device *dev)
816{
817 struct sis190_private *tp = netdev_priv(dev);
818 void __iomem *ioaddr = tp->mmio_addr;
819 unsigned long flags;
820 u32 mc_filter[2]; /* Multicast hash filter */
821 u16 rx_mode;
822
823 if (dev->flags & IFF_PROMISC) {
824 /* Unconditionally log net taps. */
825 net_drv(tp, KERN_NOTICE "%s: Promiscuous mode enabled.\n",
826 dev->name);
827 rx_mode =
828 AcceptBroadcast | AcceptMulticast | AcceptMyPhys |
829 AcceptAllPhys;
830 mc_filter[1] = mc_filter[0] = 0xffffffff;
831 } else if ((dev->mc_count > multicast_filter_limit) ||
832 (dev->flags & IFF_ALLMULTI)) {
833 /* Too many to filter perfectly -- accept all multicasts. */
834 rx_mode = AcceptBroadcast | AcceptMulticast | AcceptMyPhys;
835 mc_filter[1] = mc_filter[0] = 0xffffffff;
836 } else {
837 struct dev_mc_list *mclist;
838 unsigned int i;
839
840 rx_mode = AcceptBroadcast | AcceptMyPhys;
841 mc_filter[1] = mc_filter[0] = 0;
842 for (i = 0, mclist = dev->mc_list; mclist && i < dev->mc_count;
843 i++, mclist = mclist->next) {
844 int bit_nr =
845 ether_crc(ETH_ALEN, mclist->dmi_addr) >> 26;
846 mc_filter[bit_nr >> 5] |= 1 << (bit_nr & 31);
847 rx_mode |= AcceptMulticast;
848 }
849 }
850
851 spin_lock_irqsave(&tp->lock, flags);
852
853 SIS_W16(RxMacControl, rx_mode | 0x2);
854 SIS_W32(RxHashTable, mc_filter[0]);
855 SIS_W32(RxHashTable + 4, mc_filter[1]);
856
857 spin_unlock_irqrestore(&tp->lock, flags);
858}
859
860static void sis190_soft_reset(void __iomem *ioaddr)
861{
862 SIS_W32(IntrControl, 0x8000);
863 SIS_PCI_COMMIT();
864 msleep(1);
865 SIS_W32(IntrControl, 0x0);
866 sis190_asic_down(ioaddr);
867 msleep(1);
868}
869
870static void sis190_hw_start(struct net_device *dev)
871{
872 struct sis190_private *tp = netdev_priv(dev);
873 void __iomem *ioaddr = tp->mmio_addr;
874
875 sis190_soft_reset(ioaddr);
876
877 SIS_W32(TxDescStartAddr, tp->tx_dma);
878 SIS_W32(RxDescStartAddr, tp->rx_dma);
879
880 SIS_W32(IntrStatus, 0xffffffff);
881 SIS_W32(IntrMask, 0x0);
882 /*
883 * Default is 100Mbps.
884 * A bit strange: 100Mbps is 0x1801 elsewhere -- FR 2005/06/09
885 */
886 SIS_W16(StationControl, 0x1901);
887 SIS_W32(GMIIControl, 0x0);
888 SIS_W32(TxMacControl, 0x60);
889 SIS_W16(RxMacControl, 0x02);
890 SIS_W32(RxHashTable, 0x0);
891 SIS_W32(0x6c, 0x0);
892 SIS_W32(RxWolCtrl, 0x0);
893 SIS_W32(RxWolData, 0x0);
894
895 SIS_PCI_COMMIT();
896
897 sis190_set_rx_mode(dev);
898
899 /* Enable all known interrupts by setting the interrupt mask. */
900 SIS_W32(IntrMask, sis190_intr_mask);
901
902 SIS_W32(TxControl, 0x1a00 | CmdTxEnb);
903 SIS_W32(RxControl, 0x1a1d);
904
905 netif_start_queue(dev);
906}
907
908static void sis190_phy_task(void * data)
909{
910 struct net_device *dev = data;
911 struct sis190_private *tp = netdev_priv(dev);
912 void __iomem *ioaddr = tp->mmio_addr;
913 int phy_id = tp->mii_if.phy_id;
914 u16 val;
915
916 rtnl_lock();
917
918 val = mdio_read(ioaddr, phy_id, MII_BMCR);
919 if (val & BMCR_RESET) {
920 // FIXME: needlessly high ? -- FR 02/07/2005
921 mod_timer(&tp->timer, jiffies + HZ/10);
922 } else if (!(mdio_read_latched(ioaddr, phy_id, MII_BMSR) &
923 BMSR_ANEGCOMPLETE)) {
924 net_link(tp, KERN_WARNING "%s: PHY reset until link up.\n",
925 dev->name);
926 mdio_write(ioaddr, phy_id, MII_BMCR, val | BMCR_RESET);
927 mod_timer(&tp->timer, jiffies + SIS190_PHY_TIMEOUT);
928 } else {
929 /* Rejoice ! */
930 struct {
931 int val;
932 const char *msg;
933 u16 ctl;
934 } reg31[] = {
935 { LPA_1000XFULL | LPA_SLCT,
936 "1000 Mbps Full Duplex",
937 0x01 | _1000bpsF },
938 { LPA_1000XHALF | LPA_SLCT,
939 "1000 Mbps Half Duplex",
940 0x01 | _1000bpsH },
941 { LPA_100FULL,
942 "100 Mbps Full Duplex",
943 0x01 | _100bpsF },
944 { LPA_100HALF,
945 "100 Mbps Half Duplex",
946 0x01 | _100bpsH },
947 { LPA_10FULL,
948 "10 Mbps Full Duplex",
949 0x01 | _10bpsF },
950 { LPA_10HALF,
951 "10 Mbps Half Duplex",
952 0x01 | _10bpsH },
953 { 0, "unknown", 0x0000 }
954 }, *p;
955 u16 adv;
956
957 val = mdio_read(ioaddr, phy_id, 0x1f);
958 net_link(tp, KERN_INFO "%s: mii ext = %04x.\n", dev->name, val);
959
960 val = mdio_read(ioaddr, phy_id, MII_LPA);
961 adv = mdio_read(ioaddr, phy_id, MII_ADVERTISE);
962 net_link(tp, KERN_INFO "%s: mii lpa = %04x adv = %04x.\n",
963 dev->name, val, adv);
964
965 val &= adv;
966
967 for (p = reg31; p->ctl; p++) {
968 if ((val & p->val) == p->val)
969 break;
970 }
971 if (p->ctl)
972 SIS_W16(StationControl, p->ctl);
973 net_link(tp, KERN_INFO "%s: link on %s mode.\n", dev->name,
974 p->msg);
975 netif_carrier_on(dev);
976 }
977
978 rtnl_unlock();
979}
980
981static void sis190_phy_timer(unsigned long __opaque)
982{
983 struct net_device *dev = (struct net_device *)__opaque;
984 struct sis190_private *tp = netdev_priv(dev);
985
986 if (likely(netif_running(dev)))
987 schedule_work(&tp->phy_task);
988}
989
990static inline void sis190_delete_timer(struct net_device *dev)
991{
992 struct sis190_private *tp = netdev_priv(dev);
993
994 del_timer_sync(&tp->timer);
995}
996
997static inline void sis190_request_timer(struct net_device *dev)
998{
999 struct sis190_private *tp = netdev_priv(dev);
1000 struct timer_list *timer = &tp->timer;
1001
1002 init_timer(timer);
1003 timer->expires = jiffies + SIS190_PHY_TIMEOUT;
1004 timer->data = (unsigned long)dev;
1005 timer->function = sis190_phy_timer;
1006 add_timer(timer);
1007}
1008
1009static void sis190_set_rxbufsize(struct sis190_private *tp,
1010 struct net_device *dev)
1011{
1012 unsigned int mtu = dev->mtu;
1013
1014 tp->rx_buf_sz = (mtu > RX_BUF_SIZE) ? mtu + ETH_HLEN + 8 : RX_BUF_SIZE;
1015 /* RxDesc->size has a licence to kill the lower bits */
1016 if (tp->rx_buf_sz & 0x07) {
1017 tp->rx_buf_sz += 8;
1018 tp->rx_buf_sz &= RX_BUF_MASK;
1019 }
1020}
1021
1022static int sis190_open(struct net_device *dev)
1023{
1024 struct sis190_private *tp = netdev_priv(dev);
1025 struct pci_dev *pdev = tp->pci_dev;
1026 int rc = -ENOMEM;
1027
1028 sis190_set_rxbufsize(tp, dev);
1029
1030 /*
1031 * Rx and Tx descriptors need 256 bytes alignment.
1032 * pci_alloc_consistent() guarantees a stronger alignment.
1033 */
1034 tp->TxDescRing = pci_alloc_consistent(pdev, TX_RING_BYTES, &tp->tx_dma);
1035 if (!tp->TxDescRing)
1036 goto out;
1037
1038 tp->RxDescRing = pci_alloc_consistent(pdev, RX_RING_BYTES, &tp->rx_dma);
1039 if (!tp->RxDescRing)
1040 goto err_free_tx_0;
1041
1042 rc = sis190_init_ring(dev);
1043 if (rc < 0)
1044 goto err_free_rx_1;
1045
1046 INIT_WORK(&tp->phy_task, sis190_phy_task, dev);
1047
1048 sis190_request_timer(dev);
1049
1050 rc = request_irq(dev->irq, sis190_interrupt, SA_SHIRQ, dev->name, dev);
1051 if (rc < 0)
1052 goto err_release_timer_2;
1053
1054 sis190_hw_start(dev);
1055out:
1056 return rc;
1057
1058err_release_timer_2:
1059 sis190_delete_timer(dev);
1060 sis190_rx_clear(tp);
1061err_free_rx_1:
1062 pci_free_consistent(tp->pci_dev, RX_RING_BYTES, tp->RxDescRing,
1063 tp->rx_dma);
1064err_free_tx_0:
1065 pci_free_consistent(tp->pci_dev, TX_RING_BYTES, tp->TxDescRing,
1066 tp->tx_dma);
1067 goto out;
1068}
1069
1070static void sis190_tx_clear(struct sis190_private *tp)
1071{
1072 unsigned int i;
1073
1074 for (i = 0; i < NUM_TX_DESC; i++) {
1075 struct sk_buff *skb = tp->Tx_skbuff[i];
1076
1077 if (!skb)
1078 continue;
1079
1080 sis190_unmap_tx_skb(tp->pci_dev, skb, tp->TxDescRing + i);
1081 tp->Tx_skbuff[i] = NULL;
1082 dev_kfree_skb(skb);
1083
1084 tp->stats.tx_dropped++;
1085 }
1086 tp->cur_tx = tp->dirty_tx = 0;
1087}
1088
1089static void sis190_down(struct net_device *dev)
1090{
1091 struct sis190_private *tp = netdev_priv(dev);
1092 void __iomem *ioaddr = tp->mmio_addr;
1093 unsigned int poll_locked = 0;
1094
1095 sis190_delete_timer(dev);
1096
1097 netif_stop_queue(dev);
1098
1099 flush_scheduled_work();
1100
1101 do {
1102 spin_lock_irq(&tp->lock);
1103
1104 sis190_asic_down(ioaddr);
1105
1106 spin_unlock_irq(&tp->lock);
1107
1108 synchronize_irq(dev->irq);
1109
1110 if (!poll_locked) {
1111 netif_poll_disable(dev);
1112 poll_locked++;
1113 }
1114
1115 synchronize_sched();
1116
1117 } while (SIS_R32(IntrMask));
1118
1119 sis190_tx_clear(tp);
1120 sis190_rx_clear(tp);
1121}
1122
1123static int sis190_close(struct net_device *dev)
1124{
1125 struct sis190_private *tp = netdev_priv(dev);
1126 struct pci_dev *pdev = tp->pci_dev;
1127
1128 sis190_down(dev);
1129
1130 free_irq(dev->irq, dev);
1131
1132 netif_poll_enable(dev);
1133
1134 pci_free_consistent(pdev, TX_RING_BYTES, tp->TxDescRing, tp->tx_dma);
1135 pci_free_consistent(pdev, RX_RING_BYTES, tp->RxDescRing, tp->rx_dma);
1136
1137 tp->TxDescRing = NULL;
1138 tp->RxDescRing = NULL;
1139
1140 return 0;
1141}
1142
1143static int sis190_start_xmit(struct sk_buff *skb, struct net_device *dev)
1144{
1145 struct sis190_private *tp = netdev_priv(dev);
1146 void __iomem *ioaddr = tp->mmio_addr;
1147 u32 len, entry, dirty_tx;
1148 struct TxDesc *desc;
1149 dma_addr_t mapping;
1150
1151 if (unlikely(skb->len < ETH_ZLEN)) {
1152 skb = skb_padto(skb, ETH_ZLEN);
1153 if (!skb) {
1154 tp->stats.tx_dropped++;
1155 goto out;
1156 }
1157 len = ETH_ZLEN;
1158 } else {
1159 len = skb->len;
1160 }
1161
1162 entry = tp->cur_tx % NUM_TX_DESC;
1163 desc = tp->TxDescRing + entry;
1164
1165 if (unlikely(le32_to_cpu(desc->status) & OWNbit)) {
1166 netif_stop_queue(dev);
1167 net_tx_err(tp, KERN_ERR PFX
1168 "%s: BUG! Tx Ring full when queue awake!\n",
1169 dev->name);
1170 return NETDEV_TX_BUSY;
1171 }
1172
1173 mapping = pci_map_single(tp->pci_dev, skb->data, len, PCI_DMA_TODEVICE);
1174
1175 tp->Tx_skbuff[entry] = skb;
1176
1177 desc->PSize = cpu_to_le32(len);
1178 desc->addr = cpu_to_le32(mapping);
1179
1180 desc->size = cpu_to_le32(len);
1181 if (entry == (NUM_TX_DESC - 1))
1182 desc->size |= cpu_to_le32(RingEnd);
1183
1184 wmb();
1185
1186 desc->status = cpu_to_le32(OWNbit | INTbit | DEFbit | CRCbit | PADbit);
1187
1188 tp->cur_tx++;
1189
1190 smp_wmb();
1191
1192 SIS_W32(TxControl, 0x1a00 | CmdReset | CmdTxEnb);
1193
1194 dev->trans_start = jiffies;
1195
1196 dirty_tx = tp->dirty_tx;
1197 if ((tp->cur_tx - NUM_TX_DESC) == dirty_tx) {
1198 netif_stop_queue(dev);
1199 smp_rmb();
1200 if (dirty_tx != tp->dirty_tx)
1201 netif_wake_queue(dev);
1202 }
1203out:
1204 return NETDEV_TX_OK;
1205}
1206
1207static struct net_device_stats *sis190_get_stats(struct net_device *dev)
1208{
1209 struct sis190_private *tp = netdev_priv(dev);
1210
1211 return &tp->stats;
1212}
1213
1214static void sis190_free_phy(struct list_head *first_phy)
1215{
1216 struct sis190_phy *cur, *next;
1217
1218 list_for_each_entry_safe(cur, next, first_phy, list) {
1219 kfree(cur);
1220 }
1221}
1222
1223/**
1224 * sis190_default_phy - Select default PHY for sis190 mac.
1225 * @dev: the net device to probe for
1226 *
1227 * Select first detected PHY with link as default.
1228 * If no one is link on, select PHY whose types is HOME as default.
1229 * If HOME doesn't exist, select LAN.
1230 */
1231static u16 sis190_default_phy(struct net_device *dev)
1232{
1233 struct sis190_phy *phy, *phy_home, *phy_default, *phy_lan;
1234 struct sis190_private *tp = netdev_priv(dev);
1235 struct mii_if_info *mii_if = &tp->mii_if;
1236 void __iomem *ioaddr = tp->mmio_addr;
1237 u16 status;
1238
1239 phy_home = phy_default = phy_lan = NULL;
1240
1241 list_for_each_entry(phy, &tp->first_phy, list) {
1242 status = mdio_read_latched(ioaddr, phy->phy_id, MII_BMSR);
1243
1244 // Link ON & Not select default PHY & not ghost PHY.
1245 if ((status & BMSR_LSTATUS) &&
1246 !phy_default &&
1247 (phy->type != UNKNOWN)) {
1248 phy_default = phy;
1249 } else {
1250 status = mdio_read(ioaddr, phy->phy_id, MII_BMCR);
1251 mdio_write(ioaddr, phy->phy_id, MII_BMCR,
1252 status | BMCR_ANENABLE | BMCR_ISOLATE);
1253 if (phy->type == HOME)
1254 phy_home = phy;
1255 else if (phy->type == LAN)
1256 phy_lan = phy;
1257 }
1258 }
1259
1260 if (!phy_default) {
1261 if (phy_home)
1262 phy_default = phy_home;
1263 else if (phy_lan)
1264 phy_default = phy_lan;
1265 else
1266 phy_default = list_entry(&tp->first_phy,
1267 struct sis190_phy, list);
1268 }
1269
1270 if (mii_if->phy_id != phy_default->phy_id) {
1271 mii_if->phy_id = phy_default->phy_id;
1272 net_probe(tp, KERN_INFO
1273 "%s: Using transceiver at address %d as default.\n",
1274 pci_name(tp->pci_dev), mii_if->phy_id);
1275 }
1276
1277 status = mdio_read(ioaddr, mii_if->phy_id, MII_BMCR);
1278 status &= (~BMCR_ISOLATE);
1279
1280 mdio_write(ioaddr, mii_if->phy_id, MII_BMCR, status);
1281 status = mdio_read_latched(ioaddr, mii_if->phy_id, MII_BMSR);
1282
1283 return status;
1284}
1285
1286static void sis190_init_phy(struct net_device *dev, struct sis190_private *tp,
1287 struct sis190_phy *phy, unsigned int phy_id,
1288 u16 mii_status)
1289{
1290 void __iomem *ioaddr = tp->mmio_addr;
1291 struct mii_chip_info *p;
1292
1293 INIT_LIST_HEAD(&phy->list);
1294 phy->status = mii_status;
1295 phy->phy_id = phy_id;
1296
1297 phy->id[0] = mdio_read(ioaddr, phy_id, MII_PHYSID1);
1298 phy->id[1] = mdio_read(ioaddr, phy_id, MII_PHYSID2);
1299
1300 for (p = mii_chip_table; p->type; p++) {
1301 if ((p->id[0] == phy->id[0]) &&
1302 (p->id[1] == (phy->id[1] & 0xfff0))) {
1303 break;
1304 }
1305 }
1306
1307 if (p->id[1]) {
1308 phy->type = (p->type == MIX) ?
1309 ((mii_status & (BMSR_100FULL | BMSR_100HALF)) ?
1310 LAN : HOME) : p->type;
1311 } else
1312 phy->type = UNKNOWN;
1313
1314 net_probe(tp, KERN_INFO "%s: %s transceiver at address %d.\n",
1315 pci_name(tp->pci_dev),
1316 (phy->type == UNKNOWN) ? "Unknown PHY" : p->name, phy_id);
1317}
1318
1319/**
1320 * sis190_mii_probe - Probe MII PHY for sis190
1321 * @dev: the net device to probe for
1322 *
1323 * Search for total of 32 possible mii phy addresses.
1324 * Identify and set current phy if found one,
1325 * return error if it failed to found.
1326 */
1327static int __devinit sis190_mii_probe(struct net_device *dev)
1328{
1329 struct sis190_private *tp = netdev_priv(dev);
1330 struct mii_if_info *mii_if = &tp->mii_if;
1331 void __iomem *ioaddr = tp->mmio_addr;
1332 int phy_id;
1333 int rc = 0;
1334
1335 INIT_LIST_HEAD(&tp->first_phy);
1336
1337 for (phy_id = 0; phy_id < PHY_MAX_ADDR; phy_id++) {
1338 struct sis190_phy *phy;
1339 u16 status;
1340
1341 status = mdio_read_latched(ioaddr, phy_id, MII_BMSR);
1342
1343 // Try next mii if the current one is not accessible.
1344 if (status == 0xffff || status == 0x0000)
1345 continue;
1346
1347 phy = kmalloc(sizeof(*phy), GFP_KERNEL);
1348 if (!phy) {
1349 sis190_free_phy(&tp->first_phy);
1350 rc = -ENOMEM;
1351 goto out;
1352 }
1353
1354 sis190_init_phy(dev, tp, phy, phy_id, status);
1355
1356 list_add(&tp->first_phy, &phy->list);
1357 }
1358
1359 if (list_empty(&tp->first_phy)) {
1360 net_probe(tp, KERN_INFO "%s: No MII transceivers found!\n",
1361 pci_name(tp->pci_dev));
1362 rc = -EIO;
1363 goto out;
1364 }
1365
1366 /* Select default PHY for mac */
1367 sis190_default_phy(dev);
1368
1369 mii_if->dev = dev;
1370 mii_if->mdio_read = __mdio_read;
1371 mii_if->mdio_write = __mdio_write;
1372 mii_if->phy_id_mask = PHY_ID_ANY;
1373 mii_if->reg_num_mask = MII_REG_ANY;
1374out:
1375 return rc;
1376}
1377
1378static void __devexit sis190_mii_remove(struct net_device *dev)
1379{
1380 struct sis190_private *tp = netdev_priv(dev);
1381
1382 sis190_free_phy(&tp->first_phy);
1383}
1384
1385static void sis190_release_board(struct pci_dev *pdev)
1386{
1387 struct net_device *dev = pci_get_drvdata(pdev);
1388 struct sis190_private *tp = netdev_priv(dev);
1389
1390 iounmap(tp->mmio_addr);
1391 pci_release_regions(pdev);
1392 pci_disable_device(pdev);
1393 free_netdev(dev);
1394}
1395
1396static struct net_device * __devinit sis190_init_board(struct pci_dev *pdev)
1397{
1398 struct sis190_private *tp;
1399 struct net_device *dev;
1400 void __iomem *ioaddr;
1401 int rc;
1402
1403 dev = alloc_etherdev(sizeof(*tp));
1404 if (!dev) {
1405 net_drv(&debug, KERN_ERR PFX "unable to alloc new ethernet\n");
1406 rc = -ENOMEM;
1407 goto err_out_0;
1408 }
1409
1410 SET_MODULE_OWNER(dev);
1411 SET_NETDEV_DEV(dev, &pdev->dev);
1412
1413 tp = netdev_priv(dev);
1414 tp->msg_enable = netif_msg_init(debug.msg_enable, SIS190_MSG_DEFAULT);
1415
1416 rc = pci_enable_device(pdev);
1417 if (rc < 0) {
1418 net_probe(tp, KERN_ERR "%s: enable failure\n", pci_name(pdev));
1419 goto err_free_dev_1;
1420 }
1421
1422 rc = -ENODEV;
1423
1424 if (!(pci_resource_flags(pdev, 0) & IORESOURCE_MEM)) {
1425 net_probe(tp, KERN_ERR "%s: region #0 is no MMIO resource.\n",
1426 pci_name(pdev));
1427 goto err_pci_disable_2;
1428 }
1429 if (pci_resource_len(pdev, 0) < SIS190_REGS_SIZE) {
1430 net_probe(tp, KERN_ERR "%s: invalid PCI region size(s).\n",
1431 pci_name(pdev));
1432 goto err_pci_disable_2;
1433 }
1434
1435 rc = pci_request_regions(pdev, DRV_NAME);
1436 if (rc < 0) {
1437 net_probe(tp, KERN_ERR PFX "%s: could not request regions.\n",
1438 pci_name(pdev));
1439 goto err_pci_disable_2;
1440 }
1441
1442 rc = pci_set_dma_mask(pdev, DMA_32BIT_MASK);
1443 if (rc < 0) {
1444 net_probe(tp, KERN_ERR "%s: DMA configuration failed.\n",
1445 pci_name(pdev));
1446 goto err_free_res_3;
1447 }
1448
1449 pci_set_master(pdev);
1450
1451 ioaddr = ioremap(pci_resource_start(pdev, 0), SIS190_REGS_SIZE);
1452 if (!ioaddr) {
1453 net_probe(tp, KERN_ERR "%s: cannot remap MMIO, aborting\n",
1454 pci_name(pdev));
1455 rc = -EIO;
1456 goto err_free_res_3;
1457 }
1458
1459 tp->pci_dev = pdev;
1460 tp->mmio_addr = ioaddr;
1461
1462 sis190_irq_mask_and_ack(ioaddr);
1463
1464 sis190_soft_reset(ioaddr);
1465out:
1466 return dev;
1467
1468err_free_res_3:
1469 pci_release_regions(pdev);
1470err_pci_disable_2:
1471 pci_disable_device(pdev);
1472err_free_dev_1:
1473 free_netdev(dev);
1474err_out_0:
1475 dev = ERR_PTR(rc);
1476 goto out;
1477}
1478
1479static void sis190_tx_timeout(struct net_device *dev)
1480{
1481 struct sis190_private *tp = netdev_priv(dev);
1482 void __iomem *ioaddr = tp->mmio_addr;
1483 u8 tmp8;
1484
1485 /* Disable Tx, if not already */
1486 tmp8 = SIS_R8(TxControl);
1487 if (tmp8 & CmdTxEnb)
1488 SIS_W8(TxControl, tmp8 & ~CmdTxEnb);
1489
1490
1491 net_tx_err(tp, KERN_INFO "%s: Transmit timeout, status %08x %08x.\n",
1492 dev->name, SIS_R32(TxControl), SIS_R32(TxSts));
1493
1494 /* Disable interrupts by clearing the interrupt mask. */
1495 SIS_W32(IntrMask, 0x0000);
1496
1497 /* Stop a shared interrupt from scavenging while we are. */
1498 spin_lock_irq(&tp->lock);
1499 sis190_tx_clear(tp);
1500 spin_unlock_irq(&tp->lock);
1501
1502 /* ...and finally, reset everything. */
1503 sis190_hw_start(dev);
1504
1505 netif_wake_queue(dev);
1506}
1507
1508static int __devinit sis190_get_mac_addr_from_eeprom(struct pci_dev *pdev,
1509 struct net_device *dev)
1510{
1511 struct sis190_private *tp = netdev_priv(dev);
1512 void __iomem *ioaddr = tp->mmio_addr;
1513 u16 sig;
1514 int i;
1515
1516 net_probe(tp, KERN_INFO "%s: Read MAC address from EEPROM\n",
1517 pci_name(pdev));
1518
1519 /* Check to see if there is a sane EEPROM */
1520 sig = (u16) sis190_read_eeprom(ioaddr, EEPROMSignature);
1521
1522 if ((sig == 0xffff) || (sig == 0x0000)) {
1523 net_probe(tp, KERN_INFO "%s: Error EEPROM read %x.\n",
1524 pci_name(pdev), sig);
1525 return -EIO;
1526 }
1527
1528 /* Get MAC address from EEPROM */
1529 for (i = 0; i < MAC_ADDR_LEN / 2; i++) {
1530 __le16 w = sis190_read_eeprom(ioaddr, EEPROMMACAddr + i);
1531
1532 ((u16 *)dev->dev_addr)[0] = le16_to_cpu(w);
1533 }
1534
1535 return 0;
1536}
1537
1538/**
1539 * sis190_get_mac_addr_from_apc - Get MAC address for SiS965 model
1540 * @pdev: PCI device
1541 * @dev: network device to get address for
1542 *
1543 * SiS965 model, use APC CMOS RAM to store MAC address.
1544 * APC CMOS RAM is accessed through ISA bridge.
1545 * MAC address is read into @net_dev->dev_addr.
1546 */
1547static int __devinit sis190_get_mac_addr_from_apc(struct pci_dev *pdev,
1548 struct net_device *dev)
1549{
1550 struct sis190_private *tp = netdev_priv(dev);
1551 struct pci_dev *isa_bridge;
1552 u8 reg, tmp8;
1553 int i;
1554
1555 net_probe(tp, KERN_INFO "%s: Read MAC address from APC.\n",
1556 pci_name(pdev));
1557
1558 isa_bridge = pci_get_device(PCI_VENDOR_ID_SI, 0x0965, NULL);
1559 if (!isa_bridge) {
1560 net_probe(tp, KERN_INFO "%s: Can not find ISA bridge.\n",
1561 pci_name(pdev));
1562 return -EIO;
1563 }
1564
1565 /* Enable port 78h & 79h to access APC Registers. */
1566 pci_read_config_byte(isa_bridge, 0x48, &tmp8);
1567 reg = (tmp8 & ~0x02);
1568 pci_write_config_byte(isa_bridge, 0x48, reg);
1569 udelay(50);
1570 pci_read_config_byte(isa_bridge, 0x48, &reg);
1571
1572 for (i = 0; i < MAC_ADDR_LEN; i++) {
1573 outb(0x9 + i, 0x78);
1574 dev->dev_addr[i] = inb(0x79);
1575 }
1576
1577 outb(0x12, 0x78);
1578 reg = inb(0x79);
1579
1580 /* Restore the value to ISA Bridge */
1581 pci_write_config_byte(isa_bridge, 0x48, tmp8);
1582 pci_dev_put(isa_bridge);
1583
1584 return 0;
1585}
1586
1587/**
1588 * sis190_init_rxfilter - Initialize the Rx filter
1589 * @dev: network device to initialize
1590 *
1591 * Set receive filter address to our MAC address
1592 * and enable packet filtering.
1593 */
1594static inline void sis190_init_rxfilter(struct net_device *dev)
1595{
1596 struct sis190_private *tp = netdev_priv(dev);
1597 void __iomem *ioaddr = tp->mmio_addr;
1598 u16 ctl;
1599 int i;
1600
1601 ctl = SIS_R16(RxMacControl);
1602 /*
1603 * Disable packet filtering before setting filter.
1604 * Note: SiS's driver writes 32 bits but RxMacControl is 16 bits
1605 * only and followed by RxMacAddr (6 bytes). Strange. -- FR
1606 */
1607 SIS_W16(RxMacControl, ctl & ~0x0f00);
1608
1609 for (i = 0; i < MAC_ADDR_LEN; i++)
1610 SIS_W8(RxMacAddr + i, dev->dev_addr[i]);
1611
1612 SIS_W16(RxMacControl, ctl);
1613 SIS_PCI_COMMIT();
1614}
1615
1616static int sis190_get_mac_addr(struct pci_dev *pdev, struct net_device *dev)
1617{
1618 u8 from;
1619
1620 pci_read_config_byte(pdev, 0x73, &from);
1621
1622 return (from & 0x00000001) ?
1623 sis190_get_mac_addr_from_apc(pdev, dev) :
1624 sis190_get_mac_addr_from_eeprom(pdev, dev);
1625}
1626
1627static void sis190_set_speed_auto(struct net_device *dev)
1628{
1629 struct sis190_private *tp = netdev_priv(dev);
1630 void __iomem *ioaddr = tp->mmio_addr;
1631 int phy_id = tp->mii_if.phy_id;
1632 int val;
1633
1634 net_link(tp, KERN_INFO "%s: Enabling Auto-negotiation.\n", dev->name);
1635
1636 val = mdio_read(ioaddr, phy_id, MII_ADVERTISE);
1637
1638 // Enable 10/100 Full/Half Mode, leave MII_ADVERTISE bit4:0
1639 // unchanged.
1640 mdio_write(ioaddr, phy_id, MII_ADVERTISE, (val & ADVERTISE_SLCT) |
1641 ADVERTISE_100FULL | ADVERTISE_10FULL |
1642 ADVERTISE_100HALF | ADVERTISE_10HALF);
1643
1644 // Enable 1000 Full Mode.
1645 mdio_write(ioaddr, phy_id, MII_CTRL1000, ADVERTISE_1000FULL);
1646
1647 // Enable auto-negotiation and restart auto-negotiation.
1648 mdio_write(ioaddr, phy_id, MII_BMCR,
1649 BMCR_ANENABLE | BMCR_ANRESTART | BMCR_RESET);
1650}
1651
1652static int sis190_get_settings(struct net_device *dev, struct ethtool_cmd *cmd)
1653{
1654 struct sis190_private *tp = netdev_priv(dev);
1655
1656 return mii_ethtool_gset(&tp->mii_if, cmd);
1657}
1658
1659static int sis190_set_settings(struct net_device *dev, struct ethtool_cmd *cmd)
1660{
1661 struct sis190_private *tp = netdev_priv(dev);
1662
1663 return mii_ethtool_sset(&tp->mii_if, cmd);
1664}
1665
1666static void sis190_get_drvinfo(struct net_device *dev,
1667 struct ethtool_drvinfo *info)
1668{
1669 struct sis190_private *tp = netdev_priv(dev);
1670
1671 strcpy(info->driver, DRV_NAME);
1672 strcpy(info->version, DRV_VERSION);
1673 strcpy(info->bus_info, pci_name(tp->pci_dev));
1674}
1675
1676static int sis190_get_regs_len(struct net_device *dev)
1677{
1678 return SIS190_REGS_SIZE;
1679}
1680
1681static void sis190_get_regs(struct net_device *dev, struct ethtool_regs *regs,
1682 void *p)
1683{
1684 struct sis190_private *tp = netdev_priv(dev);
1685 unsigned long flags;
1686
1687 if (regs->len > SIS190_REGS_SIZE)
1688 regs->len = SIS190_REGS_SIZE;
1689
1690 spin_lock_irqsave(&tp->lock, flags);
1691 memcpy_fromio(p, tp->mmio_addr, regs->len);
1692 spin_unlock_irqrestore(&tp->lock, flags);
1693}
1694
1695static int sis190_nway_reset(struct net_device *dev)
1696{
1697 struct sis190_private *tp = netdev_priv(dev);
1698
1699 return mii_nway_restart(&tp->mii_if);
1700}
1701
1702static u32 sis190_get_msglevel(struct net_device *dev)
1703{
1704 struct sis190_private *tp = netdev_priv(dev);
1705
1706 return tp->msg_enable;
1707}
1708
1709static void sis190_set_msglevel(struct net_device *dev, u32 value)
1710{
1711 struct sis190_private *tp = netdev_priv(dev);
1712
1713 tp->msg_enable = value;
1714}
1715
1716static struct ethtool_ops sis190_ethtool_ops = {
1717 .get_settings = sis190_get_settings,
1718 .set_settings = sis190_set_settings,
1719 .get_drvinfo = sis190_get_drvinfo,
1720 .get_regs_len = sis190_get_regs_len,
1721 .get_regs = sis190_get_regs,
1722 .get_link = ethtool_op_get_link,
1723 .get_msglevel = sis190_get_msglevel,
1724 .set_msglevel = sis190_set_msglevel,
1725 .nway_reset = sis190_nway_reset,
1726};
1727
1728static int sis190_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd)
1729{
1730 struct sis190_private *tp = netdev_priv(dev);
1731
1732 return !netif_running(dev) ? -EINVAL :
1733 generic_mii_ioctl(&tp->mii_if, if_mii(ifr), cmd, NULL);
1734}
1735
1736static int __devinit sis190_init_one(struct pci_dev *pdev,
1737 const struct pci_device_id *ent)
1738{
1739 static int printed_version = 0;
1740 struct sis190_private *tp;
1741 struct net_device *dev;
1742 void __iomem *ioaddr;
1743 int rc;
1744
1745 if (!printed_version) {
1746 net_drv(&debug, KERN_INFO SIS190_DRIVER_NAME " loaded.\n");
1747 printed_version = 1;
1748 }
1749
1750 dev = sis190_init_board(pdev);
1751 if (IS_ERR(dev)) {
1752 rc = PTR_ERR(dev);
1753 goto out;
1754 }
1755
1756 tp = netdev_priv(dev);
1757 ioaddr = tp->mmio_addr;
1758
1759 rc = sis190_get_mac_addr(pdev, dev);
1760 if (rc < 0)
1761 goto err_release_board;
1762
1763 sis190_init_rxfilter(dev);
1764
1765 INIT_WORK(&tp->phy_task, sis190_phy_task, dev);
1766
1767 dev->open = sis190_open;
1768 dev->stop = sis190_close;
1769 dev->do_ioctl = sis190_ioctl;
1770 dev->get_stats = sis190_get_stats;
1771 dev->tx_timeout = sis190_tx_timeout;
1772 dev->watchdog_timeo = SIS190_TX_TIMEOUT;
1773 dev->hard_start_xmit = sis190_start_xmit;
1774#ifdef CONFIG_NET_POLL_CONTROLLER
1775 dev->poll_controller = sis190_netpoll;
1776#endif
1777 dev->set_multicast_list = sis190_set_rx_mode;
1778 SET_ETHTOOL_OPS(dev, &sis190_ethtool_ops);
1779 dev->irq = pdev->irq;
1780 dev->base_addr = (unsigned long) 0xdead;
1781
1782 spin_lock_init(&tp->lock);
1783
1784 rc = sis190_mii_probe(dev);
1785 if (rc < 0)
1786 goto err_release_board;
1787
1788 rc = register_netdev(dev);
1789 if (rc < 0)
1790 goto err_remove_mii;
1791
1792 pci_set_drvdata(pdev, dev);
1793
1794 net_probe(tp, KERN_INFO "%s: %s at %p (IRQ: %d), "
1795 "%2.2x:%2.2x:%2.2x:%2.2x:%2.2x:%2.2x\n",
1796 pci_name(pdev), sis_chip_info[ent->driver_data].name,
1797 ioaddr, dev->irq,
1798 dev->dev_addr[0], dev->dev_addr[1],
1799 dev->dev_addr[2], dev->dev_addr[3],
1800 dev->dev_addr[4], dev->dev_addr[5]);
1801
1802 netif_carrier_off(dev);
1803
1804 sis190_set_speed_auto(dev);
1805out:
1806 return rc;
1807
1808err_remove_mii:
1809 sis190_mii_remove(dev);
1810err_release_board:
1811 sis190_release_board(pdev);
1812 goto out;
1813}
1814
1815static void __devexit sis190_remove_one(struct pci_dev *pdev)
1816{
1817 struct net_device *dev = pci_get_drvdata(pdev);
1818
1819 sis190_mii_remove(dev);
1820 unregister_netdev(dev);
1821 sis190_release_board(pdev);
1822 pci_set_drvdata(pdev, NULL);
1823}
1824
1825static struct pci_driver sis190_pci_driver = {
1826 .name = DRV_NAME,
1827 .id_table = sis190_pci_tbl,
1828 .probe = sis190_init_one,
1829 .remove = __devexit_p(sis190_remove_one),
1830};
1831
1832static int __init sis190_init_module(void)
1833{
1834 return pci_module_init(&sis190_pci_driver);
1835}
1836
1837static void __exit sis190_cleanup_module(void)
1838{
1839 pci_unregister_driver(&sis190_pci_driver);
1840}
1841
1842module_init(sis190_init_module);
1843module_exit(sis190_cleanup_module);
diff --git a/drivers/net/tg3.c b/drivers/net/tg3.c
index 6d4ab1e333b5..af8263a1580e 100644
--- a/drivers/net/tg3.c
+++ b/drivers/net/tg3.c
@@ -340,41 +340,92 @@ static struct {
340 340
341static void tg3_write_indirect_reg32(struct tg3 *tp, u32 off, u32 val) 341static void tg3_write_indirect_reg32(struct tg3 *tp, u32 off, u32 val)
342{ 342{
343 if ((tp->tg3_flags & TG3_FLAG_PCIX_TARGET_HWBUG) != 0) { 343 unsigned long flags;
344 spin_lock_bh(&tp->indirect_lock); 344
345 pci_write_config_dword(tp->pdev, TG3PCI_REG_BASE_ADDR, off); 345 spin_lock_irqsave(&tp->indirect_lock, flags);
346 pci_write_config_dword(tp->pdev, TG3PCI_REG_DATA, val); 346 pci_write_config_dword(tp->pdev, TG3PCI_REG_BASE_ADDR, off);
347 spin_unlock_bh(&tp->indirect_lock); 347 pci_write_config_dword(tp->pdev, TG3PCI_REG_DATA, val);
348 } else { 348 spin_unlock_irqrestore(&tp->indirect_lock, flags);
349 writel(val, tp->regs + off); 349}
350 if ((tp->tg3_flags & TG3_FLAG_5701_REG_WRITE_BUG) != 0) 350
351 readl(tp->regs + off); 351static void tg3_write_flush_reg32(struct tg3 *tp, u32 off, u32 val)
352{
353 writel(val, tp->regs + off);
354 readl(tp->regs + off);
355}
356
357static u32 tg3_read_indirect_reg32(struct tg3 *tp, u32 off)
358{
359 unsigned long flags;
360 u32 val;
361
362 spin_lock_irqsave(&tp->indirect_lock, flags);
363 pci_write_config_dword(tp->pdev, TG3PCI_REG_BASE_ADDR, off);
364 pci_read_config_dword(tp->pdev, TG3PCI_REG_DATA, &val);
365 spin_unlock_irqrestore(&tp->indirect_lock, flags);
366 return val;
367}
368
369static void tg3_write_indirect_mbox(struct tg3 *tp, u32 off, u32 val)
370{
371 unsigned long flags;
372
373 if (off == (MAILBOX_RCVRET_CON_IDX_0 + TG3_64BIT_REG_LOW)) {
374 pci_write_config_dword(tp->pdev, TG3PCI_RCV_RET_RING_CON_IDX +
375 TG3_64BIT_REG_LOW, val);
376 return;
377 }
378 if (off == (MAILBOX_RCV_STD_PROD_IDX + TG3_64BIT_REG_LOW)) {
379 pci_write_config_dword(tp->pdev, TG3PCI_STD_RING_PROD_IDX +
380 TG3_64BIT_REG_LOW, val);
381 return;
382 }
383
384 spin_lock_irqsave(&tp->indirect_lock, flags);
385 pci_write_config_dword(tp->pdev, TG3PCI_REG_BASE_ADDR, off + 0x5600);
386 pci_write_config_dword(tp->pdev, TG3PCI_REG_DATA, val);
387 spin_unlock_irqrestore(&tp->indirect_lock, flags);
388
389 /* In indirect mode when disabling interrupts, we also need
390 * to clear the interrupt bit in the GRC local ctrl register.
391 */
392 if ((off == (MAILBOX_INTERRUPT_0 + TG3_64BIT_REG_LOW)) &&
393 (val == 0x1)) {
394 pci_write_config_dword(tp->pdev, TG3PCI_MISC_LOCAL_CTRL,
395 tp->grc_local_ctrl|GRC_LCLCTRL_CLEARINT);
352 } 396 }
353} 397}
354 398
399static u32 tg3_read_indirect_mbox(struct tg3 *tp, u32 off)
400{
401 unsigned long flags;
402 u32 val;
403
404 spin_lock_irqsave(&tp->indirect_lock, flags);
405 pci_write_config_dword(tp->pdev, TG3PCI_REG_BASE_ADDR, off + 0x5600);
406 pci_read_config_dword(tp->pdev, TG3PCI_REG_DATA, &val);
407 spin_unlock_irqrestore(&tp->indirect_lock, flags);
408 return val;
409}
410
355static void _tw32_flush(struct tg3 *tp, u32 off, u32 val) 411static void _tw32_flush(struct tg3 *tp, u32 off, u32 val)
356{ 412{
357 if ((tp->tg3_flags & TG3_FLAG_PCIX_TARGET_HWBUG) != 0) { 413 tp->write32(tp, off, val);
358 spin_lock_bh(&tp->indirect_lock); 414 if (!(tp->tg3_flags & TG3_FLAG_PCIX_TARGET_HWBUG) &&
359 pci_write_config_dword(tp->pdev, TG3PCI_REG_BASE_ADDR, off); 415 !(tp->tg3_flags & TG3_FLAG_5701_REG_WRITE_BUG) &&
360 pci_write_config_dword(tp->pdev, TG3PCI_REG_DATA, val); 416 !(tp->tg3_flags2 & TG3_FLG2_ICH_WORKAROUND))
361 spin_unlock_bh(&tp->indirect_lock); 417 tp->read32(tp, off); /* flush */
362 } else {
363 void __iomem *dest = tp->regs + off;
364 writel(val, dest);
365 readl(dest); /* always flush PCI write */
366 }
367} 418}
368 419
369static inline void _tw32_rx_mbox(struct tg3 *tp, u32 off, u32 val) 420static inline void tw32_mailbox_flush(struct tg3 *tp, u32 off, u32 val)
370{ 421{
371 void __iomem *mbox = tp->regs + off; 422 tp->write32_mbox(tp, off, val);
372 writel(val, mbox); 423 if (!(tp->tg3_flags & TG3_FLAG_MBOX_WRITE_REORDER) &&
373 if (tp->tg3_flags & TG3_FLAG_MBOX_WRITE_REORDER) 424 !(tp->tg3_flags2 & TG3_FLG2_ICH_WORKAROUND))
374 readl(mbox); 425 tp->read32_mbox(tp, off);
375} 426}
376 427
377static inline void _tw32_tx_mbox(struct tg3 *tp, u32 off, u32 val) 428static void tg3_write32_tx_mbox(struct tg3 *tp, u32 off, u32 val)
378{ 429{
379 void __iomem *mbox = tp->regs + off; 430 void __iomem *mbox = tp->regs + off;
380 writel(val, mbox); 431 writel(val, mbox);
@@ -384,46 +435,57 @@ static inline void _tw32_tx_mbox(struct tg3 *tp, u32 off, u32 val)
384 readl(mbox); 435 readl(mbox);
385} 436}
386 437
387#define tw32_mailbox(reg, val) writel(((val) & 0xffffffff), tp->regs + (reg)) 438static void tg3_write32(struct tg3 *tp, u32 off, u32 val)
388#define tw32_rx_mbox(reg, val) _tw32_rx_mbox(tp, reg, val) 439{
389#define tw32_tx_mbox(reg, val) _tw32_tx_mbox(tp, reg, val) 440 writel(val, tp->regs + off);
441}
442
443static u32 tg3_read32(struct tg3 *tp, u32 off)
444{
445 return (readl(tp->regs + off));
446}
447
448#define tw32_mailbox(reg, val) tp->write32_mbox(tp, reg, val)
449#define tw32_mailbox_f(reg, val) tw32_mailbox_flush(tp, (reg), (val))
450#define tw32_rx_mbox(reg, val) tp->write32_rx_mbox(tp, reg, val)
451#define tw32_tx_mbox(reg, val) tp->write32_tx_mbox(tp, reg, val)
452#define tr32_mailbox(reg) tp->read32_mbox(tp, reg)
390 453
391#define tw32(reg,val) tg3_write_indirect_reg32(tp,(reg),(val)) 454#define tw32(reg,val) tp->write32(tp, reg, val)
392#define tw32_f(reg,val) _tw32_flush(tp,(reg),(val)) 455#define tw32_f(reg,val) _tw32_flush(tp,(reg),(val))
393#define tw16(reg,val) writew(((val) & 0xffff), tp->regs + (reg)) 456#define tr32(reg) tp->read32(tp, reg)
394#define tw8(reg,val) writeb(((val) & 0xff), tp->regs + (reg))
395#define tr32(reg) readl(tp->regs + (reg))
396#define tr16(reg) readw(tp->regs + (reg))
397#define tr8(reg) readb(tp->regs + (reg))
398 457
399static void tg3_write_mem(struct tg3 *tp, u32 off, u32 val) 458static void tg3_write_mem(struct tg3 *tp, u32 off, u32 val)
400{ 459{
401 spin_lock_bh(&tp->indirect_lock); 460 unsigned long flags;
461
462 spin_lock_irqsave(&tp->indirect_lock, flags);
402 pci_write_config_dword(tp->pdev, TG3PCI_MEM_WIN_BASE_ADDR, off); 463 pci_write_config_dword(tp->pdev, TG3PCI_MEM_WIN_BASE_ADDR, off);
403 pci_write_config_dword(tp->pdev, TG3PCI_MEM_WIN_DATA, val); 464 pci_write_config_dword(tp->pdev, TG3PCI_MEM_WIN_DATA, val);
404 465
405 /* Always leave this as zero. */ 466 /* Always leave this as zero. */
406 pci_write_config_dword(tp->pdev, TG3PCI_MEM_WIN_BASE_ADDR, 0); 467 pci_write_config_dword(tp->pdev, TG3PCI_MEM_WIN_BASE_ADDR, 0);
407 spin_unlock_bh(&tp->indirect_lock); 468 spin_unlock_irqrestore(&tp->indirect_lock, flags);
408} 469}
409 470
410static void tg3_read_mem(struct tg3 *tp, u32 off, u32 *val) 471static void tg3_read_mem(struct tg3 *tp, u32 off, u32 *val)
411{ 472{
412 spin_lock_bh(&tp->indirect_lock); 473 unsigned long flags;
474
475 spin_lock_irqsave(&tp->indirect_lock, flags);
413 pci_write_config_dword(tp->pdev, TG3PCI_MEM_WIN_BASE_ADDR, off); 476 pci_write_config_dword(tp->pdev, TG3PCI_MEM_WIN_BASE_ADDR, off);
414 pci_read_config_dword(tp->pdev, TG3PCI_MEM_WIN_DATA, val); 477 pci_read_config_dword(tp->pdev, TG3PCI_MEM_WIN_DATA, val);
415 478
416 /* Always leave this as zero. */ 479 /* Always leave this as zero. */
417 pci_write_config_dword(tp->pdev, TG3PCI_MEM_WIN_BASE_ADDR, 0); 480 pci_write_config_dword(tp->pdev, TG3PCI_MEM_WIN_BASE_ADDR, 0);
418 spin_unlock_bh(&tp->indirect_lock); 481 spin_unlock_irqrestore(&tp->indirect_lock, flags);
419} 482}
420 483
421static void tg3_disable_ints(struct tg3 *tp) 484static void tg3_disable_ints(struct tg3 *tp)
422{ 485{
423 tw32(TG3PCI_MISC_HOST_CTRL, 486 tw32(TG3PCI_MISC_HOST_CTRL,
424 (tp->misc_host_ctrl | MISC_HOST_CTRL_MASK_PCI_INT)); 487 (tp->misc_host_ctrl | MISC_HOST_CTRL_MASK_PCI_INT));
425 tw32_mailbox(MAILBOX_INTERRUPT_0 + TG3_64BIT_REG_LOW, 0x00000001); 488 tw32_mailbox_f(MAILBOX_INTERRUPT_0 + TG3_64BIT_REG_LOW, 0x00000001);
426 tr32(MAILBOX_INTERRUPT_0 + TG3_64BIT_REG_LOW);
427} 489}
428 490
429static inline void tg3_cond_int(struct tg3 *tp) 491static inline void tg3_cond_int(struct tg3 *tp)
@@ -439,9 +501,8 @@ static void tg3_enable_ints(struct tg3 *tp)
439 501
440 tw32(TG3PCI_MISC_HOST_CTRL, 502 tw32(TG3PCI_MISC_HOST_CTRL,
441 (tp->misc_host_ctrl & ~MISC_HOST_CTRL_MASK_PCI_INT)); 503 (tp->misc_host_ctrl & ~MISC_HOST_CTRL_MASK_PCI_INT));
442 tw32_mailbox(MAILBOX_INTERRUPT_0 + TG3_64BIT_REG_LOW, 504 tw32_mailbox_f(MAILBOX_INTERRUPT_0 + TG3_64BIT_REG_LOW,
443 (tp->last_tag << 24)); 505 (tp->last_tag << 24));
444 tr32(MAILBOX_INTERRUPT_0 + TG3_64BIT_REG_LOW);
445 tg3_cond_int(tp); 506 tg3_cond_int(tp);
446} 507}
447 508
@@ -472,8 +533,6 @@ static inline unsigned int tg3_has_work(struct tg3 *tp)
472 */ 533 */
473static void tg3_restart_ints(struct tg3 *tp) 534static void tg3_restart_ints(struct tg3 *tp)
474{ 535{
475 tw32(TG3PCI_MISC_HOST_CTRL,
476 (tp->misc_host_ctrl & ~MISC_HOST_CTRL_MASK_PCI_INT));
477 tw32_mailbox(MAILBOX_INTERRUPT_0 + TG3_64BIT_REG_LOW, 536 tw32_mailbox(MAILBOX_INTERRUPT_0 + TG3_64BIT_REG_LOW,
478 tp->last_tag << 24); 537 tp->last_tag << 24);
479 mmiowb(); 538 mmiowb();
@@ -3278,9 +3337,8 @@ static irqreturn_t tg3_interrupt(int irq, void *dev_id, struct pt_regs *regs)
3278 /* No work, shared interrupt perhaps? re-enable 3337 /* No work, shared interrupt perhaps? re-enable
3279 * interrupts, and flush that PCI write 3338 * interrupts, and flush that PCI write
3280 */ 3339 */
3281 tw32_mailbox(MAILBOX_INTERRUPT_0 + TG3_64BIT_REG_LOW, 3340 tw32_mailbox_f(MAILBOX_INTERRUPT_0 + TG3_64BIT_REG_LOW,
3282 0x00000000); 3341 0x00000000);
3283 tr32(MAILBOX_INTERRUPT_0 + TG3_64BIT_REG_LOW);
3284 } 3342 }
3285 } else { /* shared interrupt */ 3343 } else { /* shared interrupt */
3286 handled = 0; 3344 handled = 0;
@@ -3323,9 +3381,8 @@ static irqreturn_t tg3_interrupt_tagged(int irq, void *dev_id, struct pt_regs *r
3323 /* no work, shared interrupt perhaps? re-enable 3381 /* no work, shared interrupt perhaps? re-enable
3324 * interrupts, and flush that PCI write 3382 * interrupts, and flush that PCI write
3325 */ 3383 */
3326 tw32_mailbox(MAILBOX_INTERRUPT_0 + TG3_64BIT_REG_LOW, 3384 tw32_mailbox_f(MAILBOX_INTERRUPT_0 + TG3_64BIT_REG_LOW,
3327 tp->last_tag << 24); 3385 tp->last_tag << 24);
3328 tr32(MAILBOX_INTERRUPT_0 + TG3_64BIT_REG_LOW);
3329 } 3386 }
3330 } else { /* shared interrupt */ 3387 } else { /* shared interrupt */
3331 handled = 0; 3388 handled = 0;
@@ -4216,7 +4273,7 @@ static void tg3_stop_fw(struct tg3 *);
4216static int tg3_chip_reset(struct tg3 *tp) 4273static int tg3_chip_reset(struct tg3 *tp)
4217{ 4274{
4218 u32 val; 4275 u32 val;
4219 u32 flags_save; 4276 void (*write_op)(struct tg3 *, u32, u32);
4220 int i; 4277 int i;
4221 4278
4222 if (!(tp->tg3_flags2 & TG3_FLG2_SUN_570X)) 4279 if (!(tp->tg3_flags2 & TG3_FLG2_SUN_570X))
@@ -4228,8 +4285,9 @@ static int tg3_chip_reset(struct tg3 *tp)
4228 * fun things. So, temporarily disable the 5701 4285 * fun things. So, temporarily disable the 5701
4229 * hardware workaround, while we do the reset. 4286 * hardware workaround, while we do the reset.
4230 */ 4287 */
4231 flags_save = tp->tg3_flags; 4288 write_op = tp->write32;
4232 tp->tg3_flags &= ~TG3_FLAG_5701_REG_WRITE_BUG; 4289 if (write_op == tg3_write_flush_reg32)
4290 tp->write32 = tg3_write32;
4233 4291
4234 /* do the reset */ 4292 /* do the reset */
4235 val = GRC_MISC_CFG_CORECLK_RESET; 4293 val = GRC_MISC_CFG_CORECLK_RESET;
@@ -4248,8 +4306,8 @@ static int tg3_chip_reset(struct tg3 *tp)
4248 val |= GRC_MISC_CFG_KEEP_GPHY_POWER; 4306 val |= GRC_MISC_CFG_KEEP_GPHY_POWER;
4249 tw32(GRC_MISC_CFG, val); 4307 tw32(GRC_MISC_CFG, val);
4250 4308
4251 /* restore 5701 hardware bug workaround flag */ 4309 /* restore 5701 hardware bug workaround write method */
4252 tp->tg3_flags = flags_save; 4310 tp->write32 = write_op;
4253 4311
4254 /* Unfortunately, we have to delay before the PCI read back. 4312 /* Unfortunately, we have to delay before the PCI read back.
4255 * Some 575X chips even will not respond to a PCI cfg access 4313 * Some 575X chips even will not respond to a PCI cfg access
@@ -4635,7 +4693,6 @@ static int tg3_load_firmware_cpu(struct tg3 *tp, u32 cpu_base, u32 cpu_scratch_b
4635 int cpu_scratch_size, struct fw_info *info) 4693 int cpu_scratch_size, struct fw_info *info)
4636{ 4694{
4637 int err, i; 4695 int err, i;
4638 u32 orig_tg3_flags = tp->tg3_flags;
4639 void (*write_op)(struct tg3 *, u32, u32); 4696 void (*write_op)(struct tg3 *, u32, u32);
4640 4697
4641 if (cpu_base == TX_CPU_BASE && 4698 if (cpu_base == TX_CPU_BASE &&
@@ -4651,11 +4708,6 @@ static int tg3_load_firmware_cpu(struct tg3 *tp, u32 cpu_base, u32 cpu_scratch_b
4651 else 4708 else
4652 write_op = tg3_write_indirect_reg32; 4709 write_op = tg3_write_indirect_reg32;
4653 4710
4654 /* Force use of PCI config space for indirect register
4655 * write calls.
4656 */
4657 tp->tg3_flags |= TG3_FLAG_PCIX_TARGET_HWBUG;
4658
4659 /* It is possible that bootcode is still loading at this point. 4711 /* It is possible that bootcode is still loading at this point.
4660 * Get the nvram lock first before halting the cpu. 4712 * Get the nvram lock first before halting the cpu.
4661 */ 4713 */
@@ -4691,7 +4743,6 @@ static int tg3_load_firmware_cpu(struct tg3 *tp, u32 cpu_base, u32 cpu_scratch_b
4691 err = 0; 4743 err = 0;
4692 4744
4693out: 4745out:
4694 tp->tg3_flags = orig_tg3_flags;
4695 return err; 4746 return err;
4696} 4747}
4697 4748
@@ -5808,8 +5859,7 @@ static int tg3_reset_hw(struct tg3 *tp)
5808 tw32_f(GRC_LOCAL_CTRL, tp->grc_local_ctrl); 5859 tw32_f(GRC_LOCAL_CTRL, tp->grc_local_ctrl);
5809 udelay(100); 5860 udelay(100);
5810 5861
5811 tw32_mailbox(MAILBOX_INTERRUPT_0 + TG3_64BIT_REG_LOW, 0); 5862 tw32_mailbox_f(MAILBOX_INTERRUPT_0 + TG3_64BIT_REG_LOW, 0);
5812 tr32(MAILBOX_INTERRUPT_0 + TG3_64BIT_REG_LOW);
5813 tp->last_tag = 0; 5863 tp->last_tag = 0;
5814 5864
5815 if (!(tp->tg3_flags2 & TG3_FLG2_5705_PLUS)) { 5865 if (!(tp->tg3_flags2 & TG3_FLG2_5705_PLUS)) {
@@ -6198,7 +6248,8 @@ static int tg3_test_interrupt(struct tg3 *tp)
6198 HOSTCC_MODE_NOW); 6248 HOSTCC_MODE_NOW);
6199 6249
6200 for (i = 0; i < 5; i++) { 6250 for (i = 0; i < 5; i++) {
6201 int_mbox = tr32(MAILBOX_INTERRUPT_0 + TG3_64BIT_REG_LOW); 6251 int_mbox = tr32_mailbox(MAILBOX_INTERRUPT_0 +
6252 TG3_64BIT_REG_LOW);
6202 if (int_mbox != 0) 6253 if (int_mbox != 0)
6203 break; 6254 break;
6204 msleep(10); 6255 msleep(10);
@@ -6598,10 +6649,10 @@ static int tg3_open(struct net_device *dev)
6598 6649
6599 /* Mailboxes */ 6650 /* Mailboxes */
6600 printk("DEBUG: SNDHOST_PROD[%08x%08x] SNDNIC_PROD[%08x%08x]\n", 6651 printk("DEBUG: SNDHOST_PROD[%08x%08x] SNDNIC_PROD[%08x%08x]\n",
6601 tr32(MAILBOX_SNDHOST_PROD_IDX_0 + 0x0), 6652 tr32_mailbox(MAILBOX_SNDHOST_PROD_IDX_0 + 0x0),
6602 tr32(MAILBOX_SNDHOST_PROD_IDX_0 + 0x4), 6653 tr32_mailbox(MAILBOX_SNDHOST_PROD_IDX_0 + 0x4),
6603 tr32(MAILBOX_SNDNIC_PROD_IDX_0 + 0x0), 6654 tr32_mailbox(MAILBOX_SNDNIC_PROD_IDX_0 + 0x0),
6604 tr32(MAILBOX_SNDNIC_PROD_IDX_0 + 0x4)); 6655 tr32_mailbox(MAILBOX_SNDNIC_PROD_IDX_0 + 0x4));
6605 6656
6606 /* NIC side send descriptors. */ 6657 /* NIC side send descriptors. */
6607 for (i = 0; i < 6; i++) { 6658 for (i = 0; i < 6; i++) {
@@ -7901,7 +7952,7 @@ static int tg3_test_loopback(struct tg3 *tp)
7901 num_pkts++; 7952 num_pkts++;
7902 7953
7903 tw32_tx_mbox(MAILBOX_SNDHOST_PROD_IDX_0 + TG3_64BIT_REG_LOW, send_idx); 7954 tw32_tx_mbox(MAILBOX_SNDHOST_PROD_IDX_0 + TG3_64BIT_REG_LOW, send_idx);
7904 tr32(MAILBOX_SNDHOST_PROD_IDX_0 + TG3_64BIT_REG_LOW); 7955 tr32_mailbox(MAILBOX_SNDHOST_PROD_IDX_0 + TG3_64BIT_REG_LOW);
7905 7956
7906 udelay(10); 7957 udelay(10);
7907 7958
@@ -9153,14 +9204,6 @@ static int __devinit tg3_is_sun_570X(struct tg3 *tp)
9153static int __devinit tg3_get_invariants(struct tg3 *tp) 9204static int __devinit tg3_get_invariants(struct tg3 *tp)
9154{ 9205{
9155 static struct pci_device_id write_reorder_chipsets[] = { 9206 static struct pci_device_id write_reorder_chipsets[] = {
9156 { PCI_DEVICE(PCI_VENDOR_ID_INTEL,
9157 PCI_DEVICE_ID_INTEL_82801AA_8) },
9158 { PCI_DEVICE(PCI_VENDOR_ID_INTEL,
9159 PCI_DEVICE_ID_INTEL_82801AB_8) },
9160 { PCI_DEVICE(PCI_VENDOR_ID_INTEL,
9161 PCI_DEVICE_ID_INTEL_82801BA_11) },
9162 { PCI_DEVICE(PCI_VENDOR_ID_INTEL,
9163 PCI_DEVICE_ID_INTEL_82801BA_6) },
9164 { PCI_DEVICE(PCI_VENDOR_ID_AMD, 9207 { PCI_DEVICE(PCI_VENDOR_ID_AMD,
9165 PCI_DEVICE_ID_AMD_FE_GATE_700C) }, 9208 PCI_DEVICE_ID_AMD_FE_GATE_700C) },
9166 { }, 9209 { },
@@ -9177,7 +9220,7 @@ static int __devinit tg3_get_invariants(struct tg3 *tp)
9177 tp->tg3_flags2 |= TG3_FLG2_SUN_570X; 9220 tp->tg3_flags2 |= TG3_FLG2_SUN_570X;
9178#endif 9221#endif
9179 9222
9180 /* If we have an AMD 762 or Intel ICH/ICH0/ICH2 chipset, write 9223 /* If we have an AMD 762 chipset, write
9181 * reordering to the mailbox registers done by the host 9224 * reordering to the mailbox registers done by the host
9182 * controller can cause major troubles. We read back from 9225 * controller can cause major troubles. We read back from
9183 * every mailbox register write to force the writes to be 9226 * every mailbox register write to force the writes to be
@@ -9215,6 +9258,69 @@ static int __devinit tg3_get_invariants(struct tg3 *tp)
9215 if (tp->pci_chip_rev_id == CHIPREV_ID_5752_A0_HW) 9258 if (tp->pci_chip_rev_id == CHIPREV_ID_5752_A0_HW)
9216 tp->pci_chip_rev_id = CHIPREV_ID_5752_A0; 9259 tp->pci_chip_rev_id = CHIPREV_ID_5752_A0;
9217 9260
9261 /* If we have 5702/03 A1 or A2 on certain ICH chipsets,
9262 * we need to disable memory and use config. cycles
9263 * only to access all registers. The 5702/03 chips
9264 * can mistakenly decode the special cycles from the
9265 * ICH chipsets as memory write cycles, causing corruption
9266 * of register and memory space. Only certain ICH bridges
9267 * will drive special cycles with non-zero data during the
9268 * address phase which can fall within the 5703's address
9269 * range. This is not an ICH bug as the PCI spec allows
9270 * non-zero address during special cycles. However, only
9271 * these ICH bridges are known to drive non-zero addresses
9272 * during special cycles.
9273 *
9274 * Since special cycles do not cross PCI bridges, we only
9275 * enable this workaround if the 5703 is on the secondary
9276 * bus of these ICH bridges.
9277 */
9278 if ((tp->pci_chip_rev_id == CHIPREV_ID_5703_A1) ||
9279 (tp->pci_chip_rev_id == CHIPREV_ID_5703_A2)) {
9280 static struct tg3_dev_id {
9281 u32 vendor;
9282 u32 device;
9283 u32 rev;
9284 } ich_chipsets[] = {
9285 { PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82801AA_8,
9286 PCI_ANY_ID },
9287 { PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82801AB_8,
9288 PCI_ANY_ID },
9289 { PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82801BA_11,
9290 0xa },
9291 { PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82801BA_6,
9292 PCI_ANY_ID },
9293 { },
9294 };
9295 struct tg3_dev_id *pci_id = &ich_chipsets[0];
9296 struct pci_dev *bridge = NULL;
9297
9298 while (pci_id->vendor != 0) {
9299 bridge = pci_get_device(pci_id->vendor, pci_id->device,
9300 bridge);
9301 if (!bridge) {
9302 pci_id++;
9303 continue;
9304 }
9305 if (pci_id->rev != PCI_ANY_ID) {
9306 u8 rev;
9307
9308 pci_read_config_byte(bridge, PCI_REVISION_ID,
9309 &rev);
9310 if (rev > pci_id->rev)
9311 continue;
9312 }
9313 if (bridge->subordinate &&
9314 (bridge->subordinate->number ==
9315 tp->pdev->bus->number)) {
9316
9317 tp->tg3_flags2 |= TG3_FLG2_ICH_WORKAROUND;
9318 pci_dev_put(bridge);
9319 break;
9320 }
9321 }
9322 }
9323
9218 /* Find msi capability. */ 9324 /* Find msi capability. */
9219 if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5780) 9325 if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5780)
9220 tp->msi_cap = pci_find_capability(tp->pdev, PCI_CAP_ID_MSI); 9326 tp->msi_cap = pci_find_capability(tp->pdev, PCI_CAP_ID_MSI);
@@ -9302,6 +9408,12 @@ static int __devinit tg3_get_invariants(struct tg3 *tp)
9302 } 9408 }
9303 } 9409 }
9304 9410
9411 /* 5700 BX chips need to have their TX producer index mailboxes
9412 * written twice to workaround a bug.
9413 */
9414 if (GET_CHIP_REV(tp->pci_chip_rev_id) == CHIPREV_5700_BX)
9415 tp->tg3_flags |= TG3_FLAG_TXD_MBOX_HWBUG;
9416
9305 /* Back to back register writes can cause problems on this chip, 9417 /* Back to back register writes can cause problems on this chip,
9306 * the workaround is to read back all reg writes except those to 9418 * the workaround is to read back all reg writes except those to
9307 * mailbox regs. See tg3_write_indirect_reg32(). 9419 * mailbox regs. See tg3_write_indirect_reg32().
@@ -9325,6 +9437,43 @@ static int __devinit tg3_get_invariants(struct tg3 *tp)
9325 pci_write_config_dword(tp->pdev, TG3PCI_PCISTATE, pci_state_reg); 9437 pci_write_config_dword(tp->pdev, TG3PCI_PCISTATE, pci_state_reg);
9326 } 9438 }
9327 9439
9440 /* Default fast path register access methods */
9441 tp->read32 = tg3_read32;
9442 tp->write32 = tg3_write32;
9443 tp->read32_mbox = tg3_read32;
9444 tp->write32_mbox = tg3_write32;
9445 tp->write32_tx_mbox = tg3_write32;
9446 tp->write32_rx_mbox = tg3_write32;
9447
9448 /* Various workaround register access methods */
9449 if (tp->tg3_flags & TG3_FLAG_PCIX_TARGET_HWBUG)
9450 tp->write32 = tg3_write_indirect_reg32;
9451 else if (tp->tg3_flags & TG3_FLAG_5701_REG_WRITE_BUG)
9452 tp->write32 = tg3_write_flush_reg32;
9453
9454 if ((tp->tg3_flags & TG3_FLAG_TXD_MBOX_HWBUG) ||
9455 (tp->tg3_flags & TG3_FLAG_MBOX_WRITE_REORDER)) {
9456 tp->write32_tx_mbox = tg3_write32_tx_mbox;
9457 if (tp->tg3_flags & TG3_FLAG_MBOX_WRITE_REORDER)
9458 tp->write32_rx_mbox = tg3_write_flush_reg32;
9459 }
9460
9461 if (tp->tg3_flags2 & TG3_FLG2_ICH_WORKAROUND) {
9462 tp->read32 = tg3_read_indirect_reg32;
9463 tp->write32 = tg3_write_indirect_reg32;
9464 tp->read32_mbox = tg3_read_indirect_mbox;
9465 tp->write32_mbox = tg3_write_indirect_mbox;
9466 tp->write32_tx_mbox = tg3_write_indirect_mbox;
9467 tp->write32_rx_mbox = tg3_write_indirect_mbox;
9468
9469 iounmap(tp->regs);
9470 tp->regs = 0;
9471
9472 pci_read_config_word(tp->pdev, PCI_COMMAND, &pci_cmd);
9473 pci_cmd &= ~PCI_COMMAND_MEMORY;
9474 pci_write_config_word(tp->pdev, PCI_COMMAND, pci_cmd);
9475 }
9476
9328 /* Get eeprom hw config before calling tg3_set_power_state(). 9477 /* Get eeprom hw config before calling tg3_set_power_state().
9329 * In particular, the TG3_FLAG_EEPROM_WRITE_PROT flag must be 9478 * In particular, the TG3_FLAG_EEPROM_WRITE_PROT flag must be
9330 * determined before calling tg3_set_power_state() so that 9479 * determined before calling tg3_set_power_state() so that
@@ -9539,14 +9688,6 @@ static int __devinit tg3_get_invariants(struct tg3 *tp)
9539 else 9688 else
9540 tp->tg3_flags &= ~TG3_FLAG_POLL_SERDES; 9689 tp->tg3_flags &= ~TG3_FLAG_POLL_SERDES;
9541 9690
9542 /* 5700 BX chips need to have their TX producer index mailboxes
9543 * written twice to workaround a bug.
9544 */
9545 if (GET_CHIP_REV(tp->pci_chip_rev_id) == CHIPREV_5700_BX)
9546 tp->tg3_flags |= TG3_FLAG_TXD_MBOX_HWBUG;
9547 else
9548 tp->tg3_flags &= ~TG3_FLAG_TXD_MBOX_HWBUG;
9549
9550 /* It seems all chips can get confused if TX buffers 9691 /* It seems all chips can get confused if TX buffers
9551 * straddle the 4GB address boundary in some cases. 9692 * straddle the 4GB address boundary in some cases.
9552 */ 9693 */
@@ -10469,7 +10610,10 @@ static int __devinit tg3_init_one(struct pci_dev *pdev,
10469 return 0; 10610 return 0;
10470 10611
10471err_out_iounmap: 10612err_out_iounmap:
10472 iounmap(tp->regs); 10613 if (tp->regs) {
10614 iounmap(tp->regs);
10615 tp->regs = 0;
10616 }
10473 10617
10474err_out_free_dev: 10618err_out_free_dev:
10475 free_netdev(dev); 10619 free_netdev(dev);
@@ -10491,7 +10635,10 @@ static void __devexit tg3_remove_one(struct pci_dev *pdev)
10491 struct tg3 *tp = netdev_priv(dev); 10635 struct tg3 *tp = netdev_priv(dev);
10492 10636
10493 unregister_netdev(dev); 10637 unregister_netdev(dev);
10494 iounmap(tp->regs); 10638 if (tp->regs) {
10639 iounmap(tp->regs);
10640 tp->regs = 0;
10641 }
10495 free_netdev(dev); 10642 free_netdev(dev);
10496 pci_release_regions(pdev); 10643 pci_release_regions(pdev);
10497 pci_disable_device(pdev); 10644 pci_disable_device(pdev);
diff --git a/drivers/net/tg3.h b/drivers/net/tg3.h
index 5c4433c147fa..c184b773e585 100644
--- a/drivers/net/tg3.h
+++ b/drivers/net/tg3.h
@@ -2049,6 +2049,11 @@ struct tg3 {
2049 spinlock_t lock; 2049 spinlock_t lock;
2050 spinlock_t indirect_lock; 2050 spinlock_t indirect_lock;
2051 2051
2052 u32 (*read32) (struct tg3 *, u32);
2053 void (*write32) (struct tg3 *, u32, u32);
2054 u32 (*read32_mbox) (struct tg3 *, u32);
2055 void (*write32_mbox) (struct tg3 *, u32,
2056 u32);
2052 void __iomem *regs; 2057 void __iomem *regs;
2053 struct net_device *dev; 2058 struct net_device *dev;
2054 struct pci_dev *pdev; 2059 struct pci_dev *pdev;
@@ -2060,6 +2065,8 @@ struct tg3 {
2060 u32 msg_enable; 2065 u32 msg_enable;
2061 2066
2062 /* begin "tx thread" cacheline section */ 2067 /* begin "tx thread" cacheline section */
2068 void (*write32_tx_mbox) (struct tg3 *, u32,
2069 u32);
2063 u32 tx_prod; 2070 u32 tx_prod;
2064 u32 tx_cons; 2071 u32 tx_cons;
2065 u32 tx_pending; 2072 u32 tx_pending;
@@ -2071,6 +2078,8 @@ struct tg3 {
2071 dma_addr_t tx_desc_mapping; 2078 dma_addr_t tx_desc_mapping;
2072 2079
2073 /* begin "rx thread" cacheline section */ 2080 /* begin "rx thread" cacheline section */
2081 void (*write32_rx_mbox) (struct tg3 *, u32,
2082 u32);
2074 u32 rx_rcb_ptr; 2083 u32 rx_rcb_ptr;
2075 u32 rx_std_ptr; 2084 u32 rx_std_ptr;
2076 u32 rx_jumbo_ptr; 2085 u32 rx_jumbo_ptr;
@@ -2165,6 +2174,7 @@ struct tg3 {
2165#define TG3_FLG2_ANY_SERDES (TG3_FLG2_PHY_SERDES | \ 2174#define TG3_FLG2_ANY_SERDES (TG3_FLG2_PHY_SERDES | \
2166 TG3_FLG2_MII_SERDES) 2175 TG3_FLG2_MII_SERDES)
2167#define TG3_FLG2_PARALLEL_DETECT 0x01000000 2176#define TG3_FLG2_PARALLEL_DETECT 0x01000000
2177#define TG3_FLG2_ICH_WORKAROUND 0x02000000
2168 2178
2169 u32 split_mode_max_reqs; 2179 u32 split_mode_max_reqs;
2170#define SPLIT_MODE_5704_MAX_REQ 3 2180#define SPLIT_MODE_5704_MAX_REQ 3
diff --git a/drivers/net/tulip/Kconfig b/drivers/net/tulip/Kconfig
index e2cdaf876201..8c9634a98c11 100644
--- a/drivers/net/tulip/Kconfig
+++ b/drivers/net/tulip/Kconfig
@@ -135,6 +135,18 @@ config DM9102
135 <file:Documentation/networking/net-modules.txt>. The module will 135 <file:Documentation/networking/net-modules.txt>. The module will
136 be called dmfe. 136 be called dmfe.
137 137
138config ULI526X
139 tristate "ULi M526x controller support"
140 depends on NET_TULIP && PCI
141 select CRC32
142 ---help---
143 This driver is for ULi M5261/M5263 10/100M Ethernet Controller
144 (<http://www.uli.com.tw/>).
145
146 To compile this driver as a module, choose M here and read
147 <file:Documentation/networking/net-modules.txt>. The module will
148 be called uli526x.
149
138config PCMCIA_XIRCOM 150config PCMCIA_XIRCOM
139 tristate "Xircom CardBus support (new driver)" 151 tristate "Xircom CardBus support (new driver)"
140 depends on NET_TULIP && CARDBUS 152 depends on NET_TULIP && CARDBUS
diff --git a/drivers/net/tulip/Makefile b/drivers/net/tulip/Makefile
index 8bb9b4683979..451090d6fcca 100644
--- a/drivers/net/tulip/Makefile
+++ b/drivers/net/tulip/Makefile
@@ -9,6 +9,7 @@ obj-$(CONFIG_WINBOND_840) += winbond-840.o
9obj-$(CONFIG_DE2104X) += de2104x.o 9obj-$(CONFIG_DE2104X) += de2104x.o
10obj-$(CONFIG_TULIP) += tulip.o 10obj-$(CONFIG_TULIP) += tulip.o
11obj-$(CONFIG_DE4X5) += de4x5.o 11obj-$(CONFIG_DE4X5) += de4x5.o
12obj-$(CONFIG_ULI526X) += uli526x.o
12 13
13# Declare multi-part drivers. 14# Declare multi-part drivers.
14 15
diff --git a/drivers/net/tulip/de2104x.c b/drivers/net/tulip/de2104x.c
index fc353e348f9a..a22d00198e4d 100644
--- a/drivers/net/tulip/de2104x.c
+++ b/drivers/net/tulip/de2104x.c
@@ -1934,7 +1934,7 @@ static int __init de_init_one (struct pci_dev *pdev,
1934 struct de_private *de; 1934 struct de_private *de;
1935 int rc; 1935 int rc;
1936 void __iomem *regs; 1936 void __iomem *regs;
1937 long pciaddr; 1937 unsigned long pciaddr;
1938 static int board_idx = -1; 1938 static int board_idx = -1;
1939 1939
1940 board_idx++; 1940 board_idx++;
diff --git a/drivers/net/tulip/media.c b/drivers/net/tulip/media.c
index e26c31f944bf..f53396fe79c9 100644
--- a/drivers/net/tulip/media.c
+++ b/drivers/net/tulip/media.c
@@ -81,25 +81,6 @@ int tulip_mdio_read(struct net_device *dev, int phy_id, int location)
81 return retval & 0xffff; 81 return retval & 0xffff;
82 } 82 }
83 83
84 if(tp->chip_id == ULI526X && tp->revision >= 0x40) {
85 int value;
86 int i = 1000;
87
88 value = ioread32(ioaddr + CSR9);
89 iowrite32(value & 0xFFEFFFFF, ioaddr + CSR9);
90
91 value = (phy_id << 21) | (location << 16) | 0x08000000;
92 iowrite32(value, ioaddr + CSR10);
93
94 while(--i > 0) {
95 mdio_delay();
96 if(ioread32(ioaddr + CSR10) & 0x10000000)
97 break;
98 }
99 retval = ioread32(ioaddr + CSR10);
100 spin_unlock_irqrestore(&tp->mii_lock, flags);
101 return retval & 0xFFFF;
102 }
103 /* Establish sync by sending at least 32 logic ones. */ 84 /* Establish sync by sending at least 32 logic ones. */
104 for (i = 32; i >= 0; i--) { 85 for (i = 32; i >= 0; i--) {
105 iowrite32(MDIO_ENB | MDIO_DATA_WRITE1, mdio_addr); 86 iowrite32(MDIO_ENB | MDIO_DATA_WRITE1, mdio_addr);
@@ -159,23 +140,6 @@ void tulip_mdio_write(struct net_device *dev, int phy_id, int location, int val)
159 spin_unlock_irqrestore(&tp->mii_lock, flags); 140 spin_unlock_irqrestore(&tp->mii_lock, flags);
160 return; 141 return;
161 } 142 }
162 if (tp->chip_id == ULI526X && tp->revision >= 0x40) {
163 int value;
164 int i = 1000;
165
166 value = ioread32(ioaddr + CSR9);
167 iowrite32(value & 0xFFEFFFFF, ioaddr + CSR9);
168
169 value = (phy_id << 21) | (location << 16) | 0x04000000 | (val & 0xFFFF);
170 iowrite32(value, ioaddr + CSR10);
171
172 while(--i > 0) {
173 if (ioread32(ioaddr + CSR10) & 0x10000000)
174 break;
175 }
176 spin_unlock_irqrestore(&tp->mii_lock, flags);
177 return;
178 }
179 143
180 /* Establish sync by sending 32 logic ones. */ 144 /* Establish sync by sending 32 logic ones. */
181 for (i = 32; i >= 0; i--) { 145 for (i = 32; i >= 0; i--) {
diff --git a/drivers/net/tulip/timer.c b/drivers/net/tulip/timer.c
index 691568283553..e058a9fbfe88 100644
--- a/drivers/net/tulip/timer.c
+++ b/drivers/net/tulip/timer.c
@@ -39,7 +39,6 @@ void tulip_timer(unsigned long data)
39 case MX98713: 39 case MX98713:
40 case COMPEX9881: 40 case COMPEX9881:
41 case DM910X: 41 case DM910X:
42 case ULI526X:
43 default: { 42 default: {
44 struct medialeaf *mleaf; 43 struct medialeaf *mleaf;
45 unsigned char *p; 44 unsigned char *p;
diff --git a/drivers/net/tulip/tulip.h b/drivers/net/tulip/tulip.h
index 20346d847d9e..05d2d96f7be2 100644
--- a/drivers/net/tulip/tulip.h
+++ b/drivers/net/tulip/tulip.h
@@ -88,7 +88,6 @@ enum chips {
88 I21145, 88 I21145,
89 DM910X, 89 DM910X,
90 CONEXANT, 90 CONEXANT,
91 ULI526X
92}; 91};
93 92
94 93
@@ -482,11 +481,8 @@ static inline void tulip_stop_rxtx(struct tulip_private *tp)
482 481
483static inline void tulip_restart_rxtx(struct tulip_private *tp) 482static inline void tulip_restart_rxtx(struct tulip_private *tp)
484{ 483{
485 if(!(tp->chip_id == ULI526X && 484 tulip_stop_rxtx(tp);
486 (tp->revision == 0x40 || tp->revision == 0x50))) { 485 udelay(5);
487 tulip_stop_rxtx(tp);
488 udelay(5);
489 }
490 tulip_start_rxtx(tp); 486 tulip_start_rxtx(tp);
491} 487}
492 488
diff --git a/drivers/net/tulip/tulip_core.c b/drivers/net/tulip/tulip_core.c
index d45d8f56e5b4..6266a9a7e6e3 100644
--- a/drivers/net/tulip/tulip_core.c
+++ b/drivers/net/tulip/tulip_core.c
@@ -199,9 +199,6 @@ struct tulip_chip_table tulip_tbl[] = {
199 { "Conexant LANfinity", 256, 0x0001ebef, 199 { "Conexant LANfinity", 256, 0x0001ebef,
200 HAS_MII | HAS_ACPI, tulip_timer }, 200 HAS_MII | HAS_ACPI, tulip_timer },
201 201
202 /* ULi526X */
203 { "ULi M5261/M5263", 128, 0x0001ebef,
204 HAS_MII | HAS_MEDIA_TABLE | CSR12_IN_SROM | HAS_ACPI, tulip_timer },
205}; 202};
206 203
207 204
@@ -239,10 +236,9 @@ static struct pci_device_id tulip_pci_tbl[] = {
239 { 0x1737, 0xAB09, PCI_ANY_ID, PCI_ANY_ID, 0, 0, COMET }, 236 { 0x1737, 0xAB09, PCI_ANY_ID, PCI_ANY_ID, 0, 0, COMET },
240 { 0x1737, 0xAB08, PCI_ANY_ID, PCI_ANY_ID, 0, 0, COMET }, 237 { 0x1737, 0xAB08, PCI_ANY_ID, PCI_ANY_ID, 0, 0, COMET },
241 { 0x17B3, 0xAB08, PCI_ANY_ID, PCI_ANY_ID, 0, 0, COMET }, 238 { 0x17B3, 0xAB08, PCI_ANY_ID, PCI_ANY_ID, 0, 0, COMET },
242 { 0x10b9, 0x5261, PCI_ANY_ID, PCI_ANY_ID, 0, 0, ULI526X }, /* ALi 1563 integrated ethernet */
243 { 0x10b9, 0x5263, PCI_ANY_ID, PCI_ANY_ID, 0, 0, ULI526X }, /* ALi 1563 integrated ethernet */
244 { 0x10b7, 0x9300, PCI_ANY_ID, PCI_ANY_ID, 0, 0, COMET }, /* 3Com 3CSOHO100B-TX */ 239 { 0x10b7, 0x9300, PCI_ANY_ID, PCI_ANY_ID, 0, 0, COMET }, /* 3Com 3CSOHO100B-TX */
245 { 0x14ea, 0xab08, PCI_ANY_ID, PCI_ANY_ID, 0, 0, COMET }, /* Planex FNW-3602-TX */ 240 { 0x14ea, 0xab08, PCI_ANY_ID, PCI_ANY_ID, 0, 0, COMET }, /* Planex FNW-3602-TX */
241 { 0x1414, 0x0002, PCI_ANY_ID, PCI_ANY_ID, 0, 0, COMET },
246 { } /* terminate list */ 242 { } /* terminate list */
247}; 243};
248MODULE_DEVICE_TABLE(pci, tulip_pci_tbl); 244MODULE_DEVICE_TABLE(pci, tulip_pci_tbl);
@@ -522,7 +518,7 @@ static void tulip_tx_timeout(struct net_device *dev)
522 dev->name); 518 dev->name);
523 } else if (tp->chip_id == DC21140 || tp->chip_id == DC21142 519 } else if (tp->chip_id == DC21140 || tp->chip_id == DC21142
524 || tp->chip_id == MX98713 || tp->chip_id == COMPEX9881 520 || tp->chip_id == MX98713 || tp->chip_id == COMPEX9881
525 || tp->chip_id == DM910X || tp->chip_id == ULI526X) { 521 || tp->chip_id == DM910X) {
526 printk(KERN_WARNING "%s: 21140 transmit timed out, status %8.8x, " 522 printk(KERN_WARNING "%s: 21140 transmit timed out, status %8.8x, "
527 "SIA %8.8x %8.8x %8.8x %8.8x, resetting...\n", 523 "SIA %8.8x %8.8x %8.8x %8.8x, resetting...\n",
528 dev->name, ioread32(ioaddr + CSR5), ioread32(ioaddr + CSR12), 524 dev->name, ioread32(ioaddr + CSR5), ioread32(ioaddr + CSR12),
@@ -1103,18 +1099,16 @@ static void set_rx_mode(struct net_device *dev)
1103 entry = tp->cur_tx++ % TX_RING_SIZE; 1099 entry = tp->cur_tx++ % TX_RING_SIZE;
1104 1100
1105 if (entry != 0) { 1101 if (entry != 0) {
1106 /* Avoid a chip errata by prefixing a dummy entry. Don't do 1102 /* Avoid a chip errata by prefixing a dummy entry. */
1107 this on the ULI526X as it triggers a different problem */ 1103 tp->tx_buffers[entry].skb = NULL;
1108 if (!(tp->chip_id == ULI526X && (tp->revision == 0x40 || tp->revision == 0x50))) { 1104 tp->tx_buffers[entry].mapping = 0;
1109 tp->tx_buffers[entry].skb = NULL; 1105 tp->tx_ring[entry].length =
1110 tp->tx_buffers[entry].mapping = 0; 1106 (entry == TX_RING_SIZE-1) ? cpu_to_le32(DESC_RING_WRAP) : 0;
1111 tp->tx_ring[entry].length = 1107 tp->tx_ring[entry].buffer1 = 0;
1112 (entry == TX_RING_SIZE-1) ? cpu_to_le32(DESC_RING_WRAP) : 0; 1108 /* Must set DescOwned later to avoid race with chip */
1113 tp->tx_ring[entry].buffer1 = 0; 1109 dummy = entry;
1114 /* Must set DescOwned later to avoid race with chip */ 1110 entry = tp->cur_tx++ % TX_RING_SIZE;
1115 dummy = entry; 1111
1116 entry = tp->cur_tx++ % TX_RING_SIZE;
1117 }
1118 } 1112 }
1119 1113
1120 tp->tx_buffers[entry].skb = NULL; 1114 tp->tx_buffers[entry].skb = NULL;
@@ -1235,10 +1229,6 @@ static int tulip_uli_dm_quirk(struct pci_dev *pdev)
1235{ 1229{
1236 if (pdev->vendor == 0x1282 && pdev->device == 0x9102) 1230 if (pdev->vendor == 0x1282 && pdev->device == 0x9102)
1237 return 1; 1231 return 1;
1238 if (pdev->vendor == 0x10b9 && pdev->device == 0x5261)
1239 return 1;
1240 if (pdev->vendor == 0x10b9 && pdev->device == 0x5263)
1241 return 1;
1242 return 0; 1232 return 0;
1243} 1233}
1244 1234
@@ -1680,7 +1670,6 @@ static int __devinit tulip_init_one (struct pci_dev *pdev,
1680 switch (chip_idx) { 1670 switch (chip_idx) {
1681 case DC21140: 1671 case DC21140:
1682 case DM910X: 1672 case DM910X:
1683 case ULI526X:
1684 default: 1673 default:
1685 if (tp->mtable) 1674 if (tp->mtable)
1686 iowrite32(tp->mtable->csr12dir | 0x100, ioaddr + CSR12); 1675 iowrite32(tp->mtable->csr12dir | 0x100, ioaddr + CSR12);
diff --git a/drivers/net/tulip/uli526x.c b/drivers/net/tulip/uli526x.c
new file mode 100644
index 000000000000..5ae22b7bc5ca
--- /dev/null
+++ b/drivers/net/tulip/uli526x.c
@@ -0,0 +1,1749 @@
1/*
2 This program is free software; you can redistribute it and/or
3 modify it under the terms of the GNU General Public License
4 as published by the Free Software Foundation; either version 2
5 of the License, or (at your option) any later version.
6
7 This program is distributed in the hope that it will be useful,
8 but WITHOUT ANY WARRANTY; without even the implied warranty of
9 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
10 GNU General Public License for more details.
11
12
13*/
14
15#define DRV_NAME "uli526x"
16#define DRV_VERSION "0.9.3"
17#define DRV_RELDATE "2005-7-29"
18
19#include <linux/module.h>
20
21#include <linux/kernel.h>
22#include <linux/string.h>
23#include <linux/timer.h>
24#include <linux/ptrace.h>
25#include <linux/errno.h>
26#include <linux/ioport.h>
27#include <linux/slab.h>
28#include <linux/interrupt.h>
29#include <linux/pci.h>
30#include <linux/init.h>
31#include <linux/netdevice.h>
32#include <linux/etherdevice.h>
33#include <linux/ethtool.h>
34#include <linux/skbuff.h>
35#include <linux/delay.h>
36#include <linux/spinlock.h>
37
38#include <asm/processor.h>
39#include <asm/bitops.h>
40#include <asm/io.h>
41#include <asm/dma.h>
42#include <asm/uaccess.h>
43
44
45/* Board/System/Debug information/definition ---------------- */
46#define PCI_ULI5261_ID 0x526110B9 /* ULi M5261 ID*/
47#define PCI_ULI5263_ID 0x526310B9 /* ULi M5263 ID*/
48
49#define ULI526X_IO_SIZE 0x100
50#define TX_DESC_CNT 0x20 /* Allocated Tx descriptors */
51#define RX_DESC_CNT 0x30 /* Allocated Rx descriptors */
52#define TX_FREE_DESC_CNT (TX_DESC_CNT - 2) /* Max TX packet count */
53#define TX_WAKE_DESC_CNT (TX_DESC_CNT - 3) /* TX wakeup count */
54#define DESC_ALL_CNT (TX_DESC_CNT + RX_DESC_CNT)
55#define TX_BUF_ALLOC 0x600
56#define RX_ALLOC_SIZE 0x620
57#define ULI526X_RESET 1
58#define CR0_DEFAULT 0
59#define CR6_DEFAULT 0x22200000
60#define CR7_DEFAULT 0x180c1
61#define CR15_DEFAULT 0x06 /* TxJabber RxWatchdog */
62#define TDES0_ERR_MASK 0x4302 /* TXJT, LC, EC, FUE */
63#define MAX_PACKET_SIZE 1514
64#define ULI5261_MAX_MULTICAST 14
65#define RX_COPY_SIZE 100
66#define MAX_CHECK_PACKET 0x8000
67
68#define ULI526X_10MHF 0
69#define ULI526X_100MHF 1
70#define ULI526X_10MFD 4
71#define ULI526X_100MFD 5
72#define ULI526X_AUTO 8
73
74#define ULI526X_TXTH_72 0x400000 /* TX TH 72 byte */
75#define ULI526X_TXTH_96 0x404000 /* TX TH 96 byte */
76#define ULI526X_TXTH_128 0x0000 /* TX TH 128 byte */
77#define ULI526X_TXTH_256 0x4000 /* TX TH 256 byte */
78#define ULI526X_TXTH_512 0x8000 /* TX TH 512 byte */
79#define ULI526X_TXTH_1K 0xC000 /* TX TH 1K byte */
80
81#define ULI526X_TIMER_WUT (jiffies + HZ * 1)/* timer wakeup time : 1 second */
82#define ULI526X_TX_TIMEOUT ((16*HZ)/2) /* tx packet time-out time 8 s" */
83#define ULI526X_TX_KICK (4*HZ/2) /* tx packet Kick-out time 2 s" */
84
85#define ULI526X_DBUG(dbug_now, msg, value) if (uli526x_debug || (dbug_now)) printk(KERN_ERR DRV_NAME ": %s %lx\n", (msg), (long) (value))
86
87#define SHOW_MEDIA_TYPE(mode) printk(KERN_ERR DRV_NAME ": Change Speed to %sMhz %s duplex\n",mode & 1 ?"100":"10", mode & 4 ? "full":"half");
88
89
90/* CR9 definition: SROM/MII */
91#define CR9_SROM_READ 0x4800
92#define CR9_SRCS 0x1
93#define CR9_SRCLK 0x2
94#define CR9_CRDOUT 0x8
95#define SROM_DATA_0 0x0
96#define SROM_DATA_1 0x4
97#define PHY_DATA_1 0x20000
98#define PHY_DATA_0 0x00000
99#define MDCLKH 0x10000
100
101#define PHY_POWER_DOWN 0x800
102
103#define SROM_V41_CODE 0x14
104
105#define SROM_CLK_WRITE(data, ioaddr) \
106 outl(data|CR9_SROM_READ|CR9_SRCS,ioaddr); \
107 udelay(5); \
108 outl(data|CR9_SROM_READ|CR9_SRCS|CR9_SRCLK,ioaddr); \
109 udelay(5); \
110 outl(data|CR9_SROM_READ|CR9_SRCS,ioaddr); \
111 udelay(5);
112
113/* Structure/enum declaration ------------------------------- */
114struct tx_desc {
115 u32 tdes0, tdes1, tdes2, tdes3; /* Data for the card */
116 char *tx_buf_ptr; /* Data for us */
117 struct tx_desc *next_tx_desc;
118} __attribute__(( aligned(32) ));
119
120struct rx_desc {
121 u32 rdes0, rdes1, rdes2, rdes3; /* Data for the card */
122 struct sk_buff *rx_skb_ptr; /* Data for us */
123 struct rx_desc *next_rx_desc;
124} __attribute__(( aligned(32) ));
125
126struct uli526x_board_info {
127 u32 chip_id; /* Chip vendor/Device ID */
128 struct net_device *next_dev; /* next device */
129 struct pci_dev *pdev; /* PCI device */
130 spinlock_t lock;
131
132 long ioaddr; /* I/O base address */
133 u32 cr0_data;
134 u32 cr5_data;
135 u32 cr6_data;
136 u32 cr7_data;
137 u32 cr15_data;
138
139 /* pointer for memory physical address */
140 dma_addr_t buf_pool_dma_ptr; /* Tx buffer pool memory */
141 dma_addr_t buf_pool_dma_start; /* Tx buffer pool align dword */
142 dma_addr_t desc_pool_dma_ptr; /* descriptor pool memory */
143 dma_addr_t first_tx_desc_dma;
144 dma_addr_t first_rx_desc_dma;
145
146 /* descriptor pointer */
147 unsigned char *buf_pool_ptr; /* Tx buffer pool memory */
148 unsigned char *buf_pool_start; /* Tx buffer pool align dword */
149 unsigned char *desc_pool_ptr; /* descriptor pool memory */
150 struct tx_desc *first_tx_desc;
151 struct tx_desc *tx_insert_ptr;
152 struct tx_desc *tx_remove_ptr;
153 struct rx_desc *first_rx_desc;
154 struct rx_desc *rx_insert_ptr;
155 struct rx_desc *rx_ready_ptr; /* packet come pointer */
156 unsigned long tx_packet_cnt; /* transmitted packet count */
157 unsigned long rx_avail_cnt; /* available rx descriptor count */
158 unsigned long interval_rx_cnt; /* rx packet count a callback time */
159
160 u16 dbug_cnt;
161 u16 NIC_capability; /* NIC media capability */
162 u16 PHY_reg4; /* Saved Phyxcer register 4 value */
163
164 u8 media_mode; /* user specify media mode */
165 u8 op_mode; /* real work media mode */
166 u8 phy_addr;
167 u8 link_failed; /* Ever link failed */
168 u8 wait_reset; /* Hardware failed, need to reset */
169 struct timer_list timer;
170
171 /* System defined statistic counter */
172 struct net_device_stats stats;
173
174 /* Driver defined statistic counter */
175 unsigned long tx_fifo_underrun;
176 unsigned long tx_loss_carrier;
177 unsigned long tx_no_carrier;
178 unsigned long tx_late_collision;
179 unsigned long tx_excessive_collision;
180 unsigned long tx_jabber_timeout;
181 unsigned long reset_count;
182 unsigned long reset_cr8;
183 unsigned long reset_fatal;
184 unsigned long reset_TXtimeout;
185
186 /* NIC SROM data */
187 unsigned char srom[128];
188 u8 init;
189};
190
191enum uli526x_offsets {
192 DCR0 = 0x00, DCR1 = 0x08, DCR2 = 0x10, DCR3 = 0x18, DCR4 = 0x20,
193 DCR5 = 0x28, DCR6 = 0x30, DCR7 = 0x38, DCR8 = 0x40, DCR9 = 0x48,
194 DCR10 = 0x50, DCR11 = 0x58, DCR12 = 0x60, DCR13 = 0x68, DCR14 = 0x70,
195 DCR15 = 0x78
196};
197
198enum uli526x_CR6_bits {
199 CR6_RXSC = 0x2, CR6_PBF = 0x8, CR6_PM = 0x40, CR6_PAM = 0x80,
200 CR6_FDM = 0x200, CR6_TXSC = 0x2000, CR6_STI = 0x100000,
201 CR6_SFT = 0x200000, CR6_RXA = 0x40000000, CR6_NO_PURGE = 0x20000000
202};
203
204/* Global variable declaration ----------------------------- */
205static int __devinitdata printed_version;
206static char version[] __devinitdata =
207 KERN_INFO DRV_NAME ": ULi M5261/M5263 net driver, version "
208 DRV_VERSION " (" DRV_RELDATE ")\n";
209
210static int uli526x_debug;
211static unsigned char uli526x_media_mode = ULI526X_AUTO;
212static u32 uli526x_cr6_user_set;
213
214/* For module input parameter */
215static int debug;
216static u32 cr6set;
217static unsigned char mode = 8;
218
219/* function declaration ------------------------------------- */
220static int uli526x_open(struct net_device *);
221static int uli526x_start_xmit(struct sk_buff *, struct net_device *);
222static int uli526x_stop(struct net_device *);
223static struct net_device_stats * uli526x_get_stats(struct net_device *);
224static void uli526x_set_filter_mode(struct net_device *);
225static struct ethtool_ops netdev_ethtool_ops;
226static u16 read_srom_word(long, int);
227static irqreturn_t uli526x_interrupt(int, void *, struct pt_regs *);
228static void uli526x_descriptor_init(struct uli526x_board_info *, unsigned long);
229static void allocate_rx_buffer(struct uli526x_board_info *);
230static void update_cr6(u32, unsigned long);
231static void send_filter_frame(struct net_device *, int);
232static u16 phy_read(unsigned long, u8, u8, u32);
233static u16 phy_readby_cr10(unsigned long, u8, u8);
234static void phy_write(unsigned long, u8, u8, u16, u32);
235static void phy_writeby_cr10(unsigned long, u8, u8, u16);
236static void phy_write_1bit(unsigned long, u32, u32);
237static u16 phy_read_1bit(unsigned long, u32);
238static u8 uli526x_sense_speed(struct uli526x_board_info *);
239static void uli526x_process_mode(struct uli526x_board_info *);
240static void uli526x_timer(unsigned long);
241static void uli526x_rx_packet(struct net_device *, struct uli526x_board_info *);
242static void uli526x_free_tx_pkt(struct net_device *, struct uli526x_board_info *);
243static void uli526x_reuse_skb(struct uli526x_board_info *, struct sk_buff *);
244static void uli526x_dynamic_reset(struct net_device *);
245static void uli526x_free_rxbuffer(struct uli526x_board_info *);
246static void uli526x_init(struct net_device *);
247static void uli526x_set_phyxcer(struct uli526x_board_info *);
248
249/* ULI526X network board routine ---------------------------- */
250
251/*
252 * Search ULI526X board, allocate space and register it
253 */
254
255static int __devinit uli526x_init_one (struct pci_dev *pdev,
256 const struct pci_device_id *ent)
257{
258 struct uli526x_board_info *db; /* board information structure */
259 struct net_device *dev;
260 int i, err;
261
262 ULI526X_DBUG(0, "uli526x_init_one()", 0);
263
264 if (!printed_version++)
265 printk(version);
266
267 /* Init network device */
268 dev = alloc_etherdev(sizeof(*db));
269 if (dev == NULL)
270 return -ENOMEM;
271 SET_MODULE_OWNER(dev);
272 SET_NETDEV_DEV(dev, &pdev->dev);
273
274 if (pci_set_dma_mask(pdev, DMA_32BIT_MASK)) {
275 printk(KERN_WARNING DRV_NAME ": 32-bit PCI DMA not available.\n");
276 err = -ENODEV;
277 goto err_out_free;
278 }
279
280 /* Enable Master/IO access, Disable memory access */
281 err = pci_enable_device(pdev);
282 if (err)
283 goto err_out_free;
284
285 if (!pci_resource_start(pdev, 0)) {
286 printk(KERN_ERR DRV_NAME ": I/O base is zero\n");
287 err = -ENODEV;
288 goto err_out_disable;
289 }
290
291 if (pci_resource_len(pdev, 0) < (ULI526X_IO_SIZE) ) {
292 printk(KERN_ERR DRV_NAME ": Allocated I/O size too small\n");
293 err = -ENODEV;
294 goto err_out_disable;
295 }
296
297 if (pci_request_regions(pdev, DRV_NAME)) {
298 printk(KERN_ERR DRV_NAME ": Failed to request PCI regions\n");
299 err = -ENODEV;
300 goto err_out_disable;
301 }
302
303 /* Init system & device */
304 db = netdev_priv(dev);
305
306 /* Allocate Tx/Rx descriptor memory */
307 db->desc_pool_ptr = pci_alloc_consistent(pdev, sizeof(struct tx_desc) * DESC_ALL_CNT + 0x20, &db->desc_pool_dma_ptr);
308 if(db->desc_pool_ptr == NULL)
309 {
310 err = -ENOMEM;
311 goto err_out_nomem;
312 }
313 db->buf_pool_ptr = pci_alloc_consistent(pdev, TX_BUF_ALLOC * TX_DESC_CNT + 4, &db->buf_pool_dma_ptr);
314 if(db->buf_pool_ptr == NULL)
315 {
316 err = -ENOMEM;
317 goto err_out_nomem;
318 }
319
320 db->first_tx_desc = (struct tx_desc *) db->desc_pool_ptr;
321 db->first_tx_desc_dma = db->desc_pool_dma_ptr;
322 db->buf_pool_start = db->buf_pool_ptr;
323 db->buf_pool_dma_start = db->buf_pool_dma_ptr;
324
325 db->chip_id = ent->driver_data;
326 db->ioaddr = pci_resource_start(pdev, 0);
327
328 db->pdev = pdev;
329 db->init = 1;
330
331 dev->base_addr = db->ioaddr;
332 dev->irq = pdev->irq;
333 pci_set_drvdata(pdev, dev);
334
335 /* Register some necessary functions */
336 dev->open = &uli526x_open;
337 dev->hard_start_xmit = &uli526x_start_xmit;
338 dev->stop = &uli526x_stop;
339 dev->get_stats = &uli526x_get_stats;
340 dev->set_multicast_list = &uli526x_set_filter_mode;
341 dev->ethtool_ops = &netdev_ethtool_ops;
342 spin_lock_init(&db->lock);
343
344
345 /* read 64 word srom data */
346 for (i = 0; i < 64; i++)
347 ((u16 *) db->srom)[i] = cpu_to_le16(read_srom_word(db->ioaddr, i));
348
349 /* Set Node address */
350 if(((u16 *) db->srom)[0] == 0xffff || ((u16 *) db->srom)[0] == 0) /* SROM absent, so read MAC address from ID Table */
351 {
352 outl(0x10000, db->ioaddr + DCR0); //Diagnosis mode
353 outl(0x1c0, db->ioaddr + DCR13); //Reset dianostic pointer port
354 outl(0, db->ioaddr + DCR14); //Clear reset port
355 outl(0x10, db->ioaddr + DCR14); //Reset ID Table pointer
356 outl(0, db->ioaddr + DCR14); //Clear reset port
357 outl(0, db->ioaddr + DCR13); //Clear CR13
358 outl(0x1b0, db->ioaddr + DCR13); //Select ID Table access port
359 //Read MAC address from CR14
360 for (i = 0; i < 6; i++)
361 dev->dev_addr[i] = inl(db->ioaddr + DCR14);
362 //Read end
363 outl(0, db->ioaddr + DCR13); //Clear CR13
364 outl(0, db->ioaddr + DCR0); //Clear CR0
365 udelay(10);
366 }
367 else /*Exist SROM*/
368 {
369 for (i = 0; i < 6; i++)
370 dev->dev_addr[i] = db->srom[20 + i];
371 }
372 err = register_netdev (dev);
373 if (err)
374 goto err_out_res;
375
376 printk(KERN_INFO "%s: ULi M%04lx at pci%s,",dev->name,ent->driver_data >> 16,pci_name(pdev));
377
378 for (i = 0; i < 6; i++)
379 printk("%c%02x", i ? ':' : ' ', dev->dev_addr[i]);
380 printk(", irq %d.\n", dev->irq);
381
382 pci_set_master(pdev);
383
384 return 0;
385
386err_out_res:
387 pci_release_regions(pdev);
388err_out_nomem:
389 if(db->desc_pool_ptr)
390 pci_free_consistent(pdev, sizeof(struct tx_desc) * DESC_ALL_CNT + 0x20,
391 db->desc_pool_ptr, db->desc_pool_dma_ptr);
392
393 if(db->buf_pool_ptr != NULL)
394 pci_free_consistent(pdev, TX_BUF_ALLOC * TX_DESC_CNT + 4,
395 db->buf_pool_ptr, db->buf_pool_dma_ptr);
396err_out_disable:
397 pci_disable_device(pdev);
398err_out_free:
399 pci_set_drvdata(pdev, NULL);
400 free_netdev(dev);
401
402 return err;
403}
404
405
406static void __devexit uli526x_remove_one (struct pci_dev *pdev)
407{
408 struct net_device *dev = pci_get_drvdata(pdev);
409 struct uli526x_board_info *db = netdev_priv(dev);
410
411 ULI526X_DBUG(0, "uli526x_remove_one()", 0);
412
413 pci_free_consistent(db->pdev, sizeof(struct tx_desc) *
414 DESC_ALL_CNT + 0x20, db->desc_pool_ptr,
415 db->desc_pool_dma_ptr);
416 pci_free_consistent(db->pdev, TX_BUF_ALLOC * TX_DESC_CNT + 4,
417 db->buf_pool_ptr, db->buf_pool_dma_ptr);
418 unregister_netdev(dev);
419 pci_release_regions(pdev);
420 free_netdev(dev); /* free board information */
421 pci_set_drvdata(pdev, NULL);
422 pci_disable_device(pdev);
423 ULI526X_DBUG(0, "uli526x_remove_one() exit", 0);
424}
425
426
427/*
428 * Open the interface.
429 * The interface is opened whenever "ifconfig" activates it.
430 */
431
432static int uli526x_open(struct net_device *dev)
433{
434 int ret;
435 struct uli526x_board_info *db = netdev_priv(dev);
436
437 ULI526X_DBUG(0, "uli526x_open", 0);
438
439 ret = request_irq(dev->irq, &uli526x_interrupt, SA_SHIRQ, dev->name, dev);
440 if (ret)
441 return ret;
442
443 /* system variable init */
444 db->cr6_data = CR6_DEFAULT | uli526x_cr6_user_set;
445 db->tx_packet_cnt = 0;
446 db->rx_avail_cnt = 0;
447 db->link_failed = 1;
448 netif_carrier_off(dev);
449 db->wait_reset = 0;
450
451 db->NIC_capability = 0xf; /* All capability*/
452 db->PHY_reg4 = 0x1e0;
453
454 /* CR6 operation mode decision */
455 db->cr6_data |= ULI526X_TXTH_256;
456 db->cr0_data = CR0_DEFAULT;
457
458 /* Initialize ULI526X board */
459 uli526x_init(dev);
460
461 /* Active System Interface */
462 netif_wake_queue(dev);
463
464 /* set and active a timer process */
465 init_timer(&db->timer);
466 db->timer.expires = ULI526X_TIMER_WUT + HZ * 2;
467 db->timer.data = (unsigned long)dev;
468 db->timer.function = &uli526x_timer;
469 add_timer(&db->timer);
470
471 return 0;
472}
473
474
475/* Initialize ULI526X board
476 * Reset ULI526X board
477 * Initialize TX/Rx descriptor chain structure
478 * Send the set-up frame
479 * Enable Tx/Rx machine
480 */
481
482static void uli526x_init(struct net_device *dev)
483{
484 struct uli526x_board_info *db = netdev_priv(dev);
485 unsigned long ioaddr = db->ioaddr;
486 u8 phy_tmp;
487 u16 phy_value;
488 u16 phy_reg_reset;
489
490 ULI526X_DBUG(0, "uli526x_init()", 0);
491
492 /* Reset M526x MAC controller */
493 outl(ULI526X_RESET, ioaddr + DCR0); /* RESET MAC */
494 udelay(100);
495 outl(db->cr0_data, ioaddr + DCR0);
496 udelay(5);
497
498 /* Phy addr : In some boards,M5261/M5263 phy address != 1 */
499 db->phy_addr = 1;
500 for(phy_tmp=0;phy_tmp<32;phy_tmp++)
501 {
502 phy_value=phy_read(db->ioaddr,phy_tmp,3,db->chip_id);//peer add
503 if(phy_value != 0xffff&&phy_value!=0)
504 {
505 db->phy_addr = phy_tmp;
506 break;
507 }
508 }
509 if(phy_tmp == 32)
510 printk(KERN_WARNING "Can not find the phy address!!!");
511 /* Parser SROM and media mode */
512 db->media_mode = uli526x_media_mode;
513
514 /* Phyxcer capability setting */
515 phy_reg_reset = phy_read(db->ioaddr, db->phy_addr, 0, db->chip_id);
516 phy_reg_reset = (phy_reg_reset | 0x8000);
517 phy_write(db->ioaddr, db->phy_addr, 0, phy_reg_reset, db->chip_id);
518 udelay(500);
519
520 /* Process Phyxcer Media Mode */
521 uli526x_set_phyxcer(db);
522
523 /* Media Mode Process */
524 if ( !(db->media_mode & ULI526X_AUTO) )
525 db->op_mode = db->media_mode; /* Force Mode */
526
527 /* Initialize Transmit/Receive decriptor and CR3/4 */
528 uli526x_descriptor_init(db, ioaddr);
529
530 /* Init CR6 to program M526X operation */
531 update_cr6(db->cr6_data, ioaddr);
532
533 /* Send setup frame */
534 send_filter_frame(dev, dev->mc_count); /* M5261/M5263 */
535
536 /* Init CR7, interrupt active bit */
537 db->cr7_data = CR7_DEFAULT;
538 outl(db->cr7_data, ioaddr + DCR7);
539
540 /* Init CR15, Tx jabber and Rx watchdog timer */
541 outl(db->cr15_data, ioaddr + DCR15);
542
543 /* Enable ULI526X Tx/Rx function */
544 db->cr6_data |= CR6_RXSC | CR6_TXSC;
545 update_cr6(db->cr6_data, ioaddr);
546}
547
548
549/*
550 * Hardware start transmission.
551 * Send a packet to media from the upper layer.
552 */
553
554static int uli526x_start_xmit(struct sk_buff *skb, struct net_device *dev)
555{
556 struct uli526x_board_info *db = netdev_priv(dev);
557 struct tx_desc *txptr;
558 unsigned long flags;
559
560 ULI526X_DBUG(0, "uli526x_start_xmit", 0);
561
562 /* Resource flag check */
563 netif_stop_queue(dev);
564
565 /* Too large packet check */
566 if (skb->len > MAX_PACKET_SIZE) {
567 printk(KERN_ERR DRV_NAME ": big packet = %d\n", (u16)skb->len);
568 dev_kfree_skb(skb);
569 return 0;
570 }
571
572 spin_lock_irqsave(&db->lock, flags);
573
574 /* No Tx resource check, it never happen nromally */
575 if (db->tx_packet_cnt >= TX_FREE_DESC_CNT) {
576 spin_unlock_irqrestore(&db->lock, flags);
577 printk(KERN_ERR DRV_NAME ": No Tx resource %ld\n", db->tx_packet_cnt);
578 return 1;
579 }
580
581 /* Disable NIC interrupt */
582 outl(0, dev->base_addr + DCR7);
583
584 /* transmit this packet */
585 txptr = db->tx_insert_ptr;
586 memcpy(txptr->tx_buf_ptr, skb->data, skb->len);
587 txptr->tdes1 = cpu_to_le32(0xe1000000 | skb->len);
588
589 /* Point to next transmit free descriptor */
590 db->tx_insert_ptr = txptr->next_tx_desc;
591
592 /* Transmit Packet Process */
593 if ( (db->tx_packet_cnt < TX_DESC_CNT) ) {
594 txptr->tdes0 = cpu_to_le32(0x80000000); /* Set owner bit */
595 db->tx_packet_cnt++; /* Ready to send */
596 outl(0x1, dev->base_addr + DCR1); /* Issue Tx polling */
597 dev->trans_start = jiffies; /* saved time stamp */
598 }
599
600 /* Tx resource check */
601 if ( db->tx_packet_cnt < TX_FREE_DESC_CNT )
602 netif_wake_queue(dev);
603
604 /* Restore CR7 to enable interrupt */
605 spin_unlock_irqrestore(&db->lock, flags);
606 outl(db->cr7_data, dev->base_addr + DCR7);
607
608 /* free this SKB */
609 dev_kfree_skb(skb);
610
611 return 0;
612}
613
614
615/*
616 * Stop the interface.
617 * The interface is stopped when it is brought.
618 */
619
620static int uli526x_stop(struct net_device *dev)
621{
622 struct uli526x_board_info *db = netdev_priv(dev);
623 unsigned long ioaddr = dev->base_addr;
624
625 ULI526X_DBUG(0, "uli526x_stop", 0);
626
627 /* disable system */
628 netif_stop_queue(dev);
629
630 /* deleted timer */
631 del_timer_sync(&db->timer);
632
633 /* Reset & stop ULI526X board */
634 outl(ULI526X_RESET, ioaddr + DCR0);
635 udelay(5);
636 phy_write(db->ioaddr, db->phy_addr, 0, 0x8000, db->chip_id);
637
638 /* free interrupt */
639 free_irq(dev->irq, dev);
640
641 /* free allocated rx buffer */
642 uli526x_free_rxbuffer(db);
643
644#if 0
645 /* show statistic counter */
646 printk(DRV_NAME ": FU:%lx EC:%lx LC:%lx NC:%lx LOC:%lx TXJT:%lx RESET:%lx RCR8:%lx FAL:%lx TT:%lx\n",
647 db->tx_fifo_underrun, db->tx_excessive_collision,
648 db->tx_late_collision, db->tx_no_carrier, db->tx_loss_carrier,
649 db->tx_jabber_timeout, db->reset_count, db->reset_cr8,
650 db->reset_fatal, db->reset_TXtimeout);
651#endif
652
653 return 0;
654}
655
656
657/*
658 * M5261/M5263 insterrupt handler
659 * receive the packet to upper layer, free the transmitted packet
660 */
661
662static irqreturn_t uli526x_interrupt(int irq, void *dev_id, struct pt_regs *regs)
663{
664 struct net_device *dev = dev_id;
665 struct uli526x_board_info *db = netdev_priv(dev);
666 unsigned long ioaddr = dev->base_addr;
667 unsigned long flags;
668
669 if (!dev) {
670 ULI526X_DBUG(1, "uli526x_interrupt() without DEVICE arg", 0);
671 return IRQ_NONE;
672 }
673
674 spin_lock_irqsave(&db->lock, flags);
675 outl(0, ioaddr + DCR7);
676
677 /* Got ULI526X status */
678 db->cr5_data = inl(ioaddr + DCR5);
679 outl(db->cr5_data, ioaddr + DCR5);
680 if ( !(db->cr5_data & 0x180c1) ) {
681 spin_unlock_irqrestore(&db->lock, flags);
682 outl(db->cr7_data, ioaddr + DCR7);
683 return IRQ_HANDLED;
684 }
685
686 /* Check system status */
687 if (db->cr5_data & 0x2000) {
688 /* system bus error happen */
689 ULI526X_DBUG(1, "System bus error happen. CR5=", db->cr5_data);
690 db->reset_fatal++;
691 db->wait_reset = 1; /* Need to RESET */
692 spin_unlock_irqrestore(&db->lock, flags);
693 return IRQ_HANDLED;
694 }
695
696 /* Received the coming packet */
697 if ( (db->cr5_data & 0x40) && db->rx_avail_cnt )
698 uli526x_rx_packet(dev, db);
699
700 /* reallocate rx descriptor buffer */
701 if (db->rx_avail_cnt<RX_DESC_CNT)
702 allocate_rx_buffer(db);
703
704 /* Free the transmitted descriptor */
705 if ( db->cr5_data & 0x01)
706 uli526x_free_tx_pkt(dev, db);
707
708 /* Restore CR7 to enable interrupt mask */
709 outl(db->cr7_data, ioaddr + DCR7);
710
711 spin_unlock_irqrestore(&db->lock, flags);
712 return IRQ_HANDLED;
713}
714
715
716/*
717 * Free TX resource after TX complete
718 */
719
720static void uli526x_free_tx_pkt(struct net_device *dev, struct uli526x_board_info * db)
721{
722 struct tx_desc *txptr;
723 u32 tdes0;
724
725 txptr = db->tx_remove_ptr;
726 while(db->tx_packet_cnt) {
727 tdes0 = le32_to_cpu(txptr->tdes0);
728 /* printk(DRV_NAME ": tdes0=%x\n", tdes0); */
729 if (tdes0 & 0x80000000)
730 break;
731
732 /* A packet sent completed */
733 db->tx_packet_cnt--;
734 db->stats.tx_packets++;
735
736 /* Transmit statistic counter */
737 if ( tdes0 != 0x7fffffff ) {
738 /* printk(DRV_NAME ": tdes0=%x\n", tdes0); */
739 db->stats.collisions += (tdes0 >> 3) & 0xf;
740 db->stats.tx_bytes += le32_to_cpu(txptr->tdes1) & 0x7ff;
741 if (tdes0 & TDES0_ERR_MASK) {
742 db->stats.tx_errors++;
743 if (tdes0 & 0x0002) { /* UnderRun */
744 db->tx_fifo_underrun++;
745 if ( !(db->cr6_data & CR6_SFT) ) {
746 db->cr6_data = db->cr6_data | CR6_SFT;
747 update_cr6(db->cr6_data, db->ioaddr);
748 }
749 }
750 if (tdes0 & 0x0100)
751 db->tx_excessive_collision++;
752 if (tdes0 & 0x0200)
753 db->tx_late_collision++;
754 if (tdes0 & 0x0400)
755 db->tx_no_carrier++;
756 if (tdes0 & 0x0800)
757 db->tx_loss_carrier++;
758 if (tdes0 & 0x4000)
759 db->tx_jabber_timeout++;
760 }
761 }
762
763 txptr = txptr->next_tx_desc;
764 }/* End of while */
765
766 /* Update TX remove pointer to next */
767 db->tx_remove_ptr = txptr;
768
769 /* Resource available check */
770 if ( db->tx_packet_cnt < TX_WAKE_DESC_CNT )
771 netif_wake_queue(dev); /* Active upper layer, send again */
772}
773
774
775/*
776 * Receive the come packet and pass to upper layer
777 */
778
779static void uli526x_rx_packet(struct net_device *dev, struct uli526x_board_info * db)
780{
781 struct rx_desc *rxptr;
782 struct sk_buff *skb;
783 int rxlen;
784 u32 rdes0;
785
786 rxptr = db->rx_ready_ptr;
787
788 while(db->rx_avail_cnt) {
789 rdes0 = le32_to_cpu(rxptr->rdes0);
790 if (rdes0 & 0x80000000) /* packet owner check */
791 {
792 break;
793 }
794
795 db->rx_avail_cnt--;
796 db->interval_rx_cnt++;
797
798 pci_unmap_single(db->pdev, le32_to_cpu(rxptr->rdes2), RX_ALLOC_SIZE, PCI_DMA_FROMDEVICE);
799 if ( (rdes0 & 0x300) != 0x300) {
800 /* A packet without First/Last flag */
801 /* reuse this SKB */
802 ULI526X_DBUG(0, "Reuse SK buffer, rdes0", rdes0);
803 uli526x_reuse_skb(db, rxptr->rx_skb_ptr);
804 } else {
805 /* A packet with First/Last flag */
806 rxlen = ( (rdes0 >> 16) & 0x3fff) - 4;
807
808 /* error summary bit check */
809 if (rdes0 & 0x8000) {
810 /* This is a error packet */
811 //printk(DRV_NAME ": rdes0: %lx\n", rdes0);
812 db->stats.rx_errors++;
813 if (rdes0 & 1)
814 db->stats.rx_fifo_errors++;
815 if (rdes0 & 2)
816 db->stats.rx_crc_errors++;
817 if (rdes0 & 0x80)
818 db->stats.rx_length_errors++;
819 }
820
821 if ( !(rdes0 & 0x8000) ||
822 ((db->cr6_data & CR6_PM) && (rxlen>6)) ) {
823 skb = rxptr->rx_skb_ptr;
824
825 /* Good packet, send to upper layer */
826 /* Shorst packet used new SKB */
827 if ( (rxlen < RX_COPY_SIZE) &&
828 ( (skb = dev_alloc_skb(rxlen + 2) )
829 != NULL) ) {
830 /* size less than COPY_SIZE, allocate a rxlen SKB */
831 skb->dev = dev;
832 skb_reserve(skb, 2); /* 16byte align */
833 memcpy(skb_put(skb, rxlen), rxptr->rx_skb_ptr->tail, rxlen);
834 uli526x_reuse_skb(db, rxptr->rx_skb_ptr);
835 } else {
836 skb->dev = dev;
837 skb_put(skb, rxlen);
838 }
839 skb->protocol = eth_type_trans(skb, dev);
840 netif_rx(skb);
841 dev->last_rx = jiffies;
842 db->stats.rx_packets++;
843 db->stats.rx_bytes += rxlen;
844
845 } else {
846 /* Reuse SKB buffer when the packet is error */
847 ULI526X_DBUG(0, "Reuse SK buffer, rdes0", rdes0);
848 uli526x_reuse_skb(db, rxptr->rx_skb_ptr);
849 }
850 }
851
852 rxptr = rxptr->next_rx_desc;
853 }
854
855 db->rx_ready_ptr = rxptr;
856}
857
858
859/*
860 * Get statistics from driver.
861 */
862
863static struct net_device_stats * uli526x_get_stats(struct net_device *dev)
864{
865 struct uli526x_board_info *db = netdev_priv(dev);
866
867 ULI526X_DBUG(0, "uli526x_get_stats", 0);
868 return &db->stats;
869}
870
871
872/*
873 * Set ULI526X multicast address
874 */
875
876static void uli526x_set_filter_mode(struct net_device * dev)
877{
878 struct uli526x_board_info *db = dev->priv;
879 unsigned long flags;
880
881 ULI526X_DBUG(0, "uli526x_set_filter_mode()", 0);
882 spin_lock_irqsave(&db->lock, flags);
883
884 if (dev->flags & IFF_PROMISC) {
885 ULI526X_DBUG(0, "Enable PROM Mode", 0);
886 db->cr6_data |= CR6_PM | CR6_PBF;
887 update_cr6(db->cr6_data, db->ioaddr);
888 spin_unlock_irqrestore(&db->lock, flags);
889 return;
890 }
891
892 if (dev->flags & IFF_ALLMULTI || dev->mc_count > ULI5261_MAX_MULTICAST) {
893 ULI526X_DBUG(0, "Pass all multicast address", dev->mc_count);
894 db->cr6_data &= ~(CR6_PM | CR6_PBF);
895 db->cr6_data |= CR6_PAM;
896 spin_unlock_irqrestore(&db->lock, flags);
897 return;
898 }
899
900 ULI526X_DBUG(0, "Set multicast address", dev->mc_count);
901 send_filter_frame(dev, dev->mc_count); /* M5261/M5263 */
902 spin_unlock_irqrestore(&db->lock, flags);
903}
904
905static void
906ULi_ethtool_gset(struct uli526x_board_info *db, struct ethtool_cmd *ecmd)
907{
908 ecmd->supported = (SUPPORTED_10baseT_Half |
909 SUPPORTED_10baseT_Full |
910 SUPPORTED_100baseT_Half |
911 SUPPORTED_100baseT_Full |
912 SUPPORTED_Autoneg |
913 SUPPORTED_MII);
914
915 ecmd->advertising = (ADVERTISED_10baseT_Half |
916 ADVERTISED_10baseT_Full |
917 ADVERTISED_100baseT_Half |
918 ADVERTISED_100baseT_Full |
919 ADVERTISED_Autoneg |
920 ADVERTISED_MII);
921
922
923 ecmd->port = PORT_MII;
924 ecmd->phy_address = db->phy_addr;
925
926 ecmd->transceiver = XCVR_EXTERNAL;
927
928 ecmd->speed = 10;
929 ecmd->duplex = DUPLEX_HALF;
930
931 if(db->op_mode==ULI526X_100MHF || db->op_mode==ULI526X_100MFD)
932 {
933 ecmd->speed = 100;
934 }
935 if(db->op_mode==ULI526X_10MFD || db->op_mode==ULI526X_100MFD)
936 {
937 ecmd->duplex = DUPLEX_FULL;
938 }
939 if(db->link_failed)
940 {
941 ecmd->speed = -1;
942 ecmd->duplex = -1;
943 }
944
945 if (db->media_mode & ULI526X_AUTO)
946 {
947 ecmd->autoneg = AUTONEG_ENABLE;
948 }
949}
950
951static void netdev_get_drvinfo(struct net_device *dev,
952 struct ethtool_drvinfo *info)
953{
954 struct uli526x_board_info *np = netdev_priv(dev);
955
956 strcpy(info->driver, DRV_NAME);
957 strcpy(info->version, DRV_VERSION);
958 if (np->pdev)
959 strcpy(info->bus_info, pci_name(np->pdev));
960 else
961 sprintf(info->bus_info, "EISA 0x%lx %d",
962 dev->base_addr, dev->irq);
963}
964
965static int netdev_get_settings(struct net_device *dev, struct ethtool_cmd *cmd) {
966 struct uli526x_board_info *np = netdev_priv(dev);
967
968 ULi_ethtool_gset(np, cmd);
969
970 return 0;
971}
972
973static u32 netdev_get_link(struct net_device *dev) {
974 struct uli526x_board_info *np = netdev_priv(dev);
975
976 if(np->link_failed)
977 return 0;
978 else
979 return 1;
980}
981
982static void uli526x_get_wol(struct net_device *dev, struct ethtool_wolinfo *wol)
983{
984 wol->supported = WAKE_PHY | WAKE_MAGIC;
985 wol->wolopts = 0;
986}
987
988static struct ethtool_ops netdev_ethtool_ops = {
989 .get_drvinfo = netdev_get_drvinfo,
990 .get_settings = netdev_get_settings,
991 .get_link = netdev_get_link,
992 .get_wol = uli526x_get_wol,
993};
994
995/*
996 * A periodic timer routine
997 * Dynamic media sense, allocate Rx buffer...
998 */
999
1000static void uli526x_timer(unsigned long data)
1001{
1002 u32 tmp_cr8;
1003 unsigned char tmp_cr12=0;
1004 struct net_device *dev = (struct net_device *) data;
1005 struct uli526x_board_info *db = netdev_priv(dev);
1006 unsigned long flags;
1007 u8 TmpSpeed=10;
1008
1009 //ULI526X_DBUG(0, "uli526x_timer()", 0);
1010 spin_lock_irqsave(&db->lock, flags);
1011
1012
1013 /* Dynamic reset ULI526X : system error or transmit time-out */
1014 tmp_cr8 = inl(db->ioaddr + DCR8);
1015 if ( (db->interval_rx_cnt==0) && (tmp_cr8) ) {
1016 db->reset_cr8++;
1017 db->wait_reset = 1;
1018 }
1019 db->interval_rx_cnt = 0;
1020
1021 /* TX polling kick monitor */
1022 if ( db->tx_packet_cnt &&
1023 time_after(jiffies, dev->trans_start + ULI526X_TX_KICK) ) {
1024 outl(0x1, dev->base_addr + DCR1); // Tx polling again
1025
1026 // TX Timeout
1027 if ( time_after(jiffies, dev->trans_start + ULI526X_TX_TIMEOUT) ) {
1028 db->reset_TXtimeout++;
1029 db->wait_reset = 1;
1030 printk( "%s: Tx timeout - resetting\n",
1031 dev->name);
1032 }
1033 }
1034
1035 if (db->wait_reset) {
1036 ULI526X_DBUG(0, "Dynamic Reset device", db->tx_packet_cnt);
1037 db->reset_count++;
1038 uli526x_dynamic_reset(dev);
1039 db->timer.expires = ULI526X_TIMER_WUT;
1040 add_timer(&db->timer);
1041 spin_unlock_irqrestore(&db->lock, flags);
1042 return;
1043 }
1044
1045 /* Link status check, Dynamic media type change */
1046 if((phy_read(db->ioaddr, db->phy_addr, 5, db->chip_id) & 0x01e0)!=0)
1047 tmp_cr12 = 3;
1048
1049 if ( !(tmp_cr12 & 0x3) && !db->link_failed ) {
1050 /* Link Failed */
1051 ULI526X_DBUG(0, "Link Failed", tmp_cr12);
1052 netif_carrier_off(dev);
1053 printk(KERN_INFO "uli526x: %s NIC Link is Down\n",dev->name);
1054 db->link_failed = 1;
1055
1056 /* For Force 10/100M Half/Full mode: Enable Auto-Nego mode */
1057 /* AUTO don't need */
1058 if ( !(db->media_mode & 0x8) )
1059 phy_write(db->ioaddr, db->phy_addr, 0, 0x1000, db->chip_id);
1060
1061 /* AUTO mode, if INT phyxcer link failed, select EXT device */
1062 if (db->media_mode & ULI526X_AUTO) {
1063 db->cr6_data&=~0x00000200; /* bit9=0, HD mode */
1064 update_cr6(db->cr6_data, db->ioaddr);
1065 }
1066 } else
1067 if ((tmp_cr12 & 0x3) && db->link_failed) {
1068 ULI526X_DBUG(0, "Link link OK", tmp_cr12);
1069 db->link_failed = 0;
1070
1071 /* Auto Sense Speed */
1072 if ( (db->media_mode & ULI526X_AUTO) &&
1073 uli526x_sense_speed(db) )
1074 db->link_failed = 1;
1075 uli526x_process_mode(db);
1076
1077 if(db->link_failed==0)
1078 {
1079 if(db->op_mode==ULI526X_100MHF || db->op_mode==ULI526X_100MFD)
1080 {
1081 TmpSpeed = 100;
1082 }
1083 if(db->op_mode==ULI526X_10MFD || db->op_mode==ULI526X_100MFD)
1084 {
1085 printk(KERN_INFO "uli526x: %s NIC Link is Up %d Mbps Full duplex\n",dev->name,TmpSpeed);
1086 }
1087 else
1088 {
1089 printk(KERN_INFO "uli526x: %s NIC Link is Up %d Mbps Half duplex\n",dev->name,TmpSpeed);
1090 }
1091 netif_carrier_on(dev);
1092 }
1093 /* SHOW_MEDIA_TYPE(db->op_mode); */
1094 }
1095 else if(!(tmp_cr12 & 0x3) && db->link_failed)
1096 {
1097 if(db->init==1)
1098 {
1099 printk(KERN_INFO "uli526x: %s NIC Link is Down\n",dev->name);
1100 netif_carrier_off(dev);
1101 }
1102 }
1103 db->init=0;
1104
1105 /* Timer active again */
1106 db->timer.expires = ULI526X_TIMER_WUT;
1107 add_timer(&db->timer);
1108 spin_unlock_irqrestore(&db->lock, flags);
1109}
1110
1111
1112/*
1113 * Dynamic reset the ULI526X board
1114 * Stop ULI526X board
1115 * Free Tx/Rx allocated memory
1116 * Reset ULI526X board
1117 * Re-initialize ULI526X board
1118 */
1119
1120static void uli526x_dynamic_reset(struct net_device *dev)
1121{
1122 struct uli526x_board_info *db = netdev_priv(dev);
1123
1124 ULI526X_DBUG(0, "uli526x_dynamic_reset()", 0);
1125
1126 /* Sopt MAC controller */
1127 db->cr6_data &= ~(CR6_RXSC | CR6_TXSC); /* Disable Tx/Rx */
1128 update_cr6(db->cr6_data, dev->base_addr);
1129 outl(0, dev->base_addr + DCR7); /* Disable Interrupt */
1130 outl(inl(dev->base_addr + DCR5), dev->base_addr + DCR5);
1131
1132 /* Disable upper layer interface */
1133 netif_stop_queue(dev);
1134
1135 /* Free Rx Allocate buffer */
1136 uli526x_free_rxbuffer(db);
1137
1138 /* system variable init */
1139 db->tx_packet_cnt = 0;
1140 db->rx_avail_cnt = 0;
1141 db->link_failed = 1;
1142 db->init=1;
1143 db->wait_reset = 0;
1144
1145 /* Re-initialize ULI526X board */
1146 uli526x_init(dev);
1147
1148 /* Restart upper layer interface */
1149 netif_wake_queue(dev);
1150}
1151
1152
1153/*
1154 * free all allocated rx buffer
1155 */
1156
1157static void uli526x_free_rxbuffer(struct uli526x_board_info * db)
1158{
1159 ULI526X_DBUG(0, "uli526x_free_rxbuffer()", 0);
1160
1161 /* free allocated rx buffer */
1162 while (db->rx_avail_cnt) {
1163 dev_kfree_skb(db->rx_ready_ptr->rx_skb_ptr);
1164 db->rx_ready_ptr = db->rx_ready_ptr->next_rx_desc;
1165 db->rx_avail_cnt--;
1166 }
1167}
1168
1169
1170/*
1171 * Reuse the SK buffer
1172 */
1173
1174static void uli526x_reuse_skb(struct uli526x_board_info *db, struct sk_buff * skb)
1175{
1176 struct rx_desc *rxptr = db->rx_insert_ptr;
1177
1178 if (!(rxptr->rdes0 & cpu_to_le32(0x80000000))) {
1179 rxptr->rx_skb_ptr = skb;
1180 rxptr->rdes2 = cpu_to_le32( pci_map_single(db->pdev, skb->tail, RX_ALLOC_SIZE, PCI_DMA_FROMDEVICE) );
1181 wmb();
1182 rxptr->rdes0 = cpu_to_le32(0x80000000);
1183 db->rx_avail_cnt++;
1184 db->rx_insert_ptr = rxptr->next_rx_desc;
1185 } else
1186 ULI526X_DBUG(0, "SK Buffer reuse method error", db->rx_avail_cnt);
1187}
1188
1189
1190/*
1191 * Initialize transmit/Receive descriptor
1192 * Using Chain structure, and allocate Tx/Rx buffer
1193 */
1194
1195static void uli526x_descriptor_init(struct uli526x_board_info *db, unsigned long ioaddr)
1196{
1197 struct tx_desc *tmp_tx;
1198 struct rx_desc *tmp_rx;
1199 unsigned char *tmp_buf;
1200 dma_addr_t tmp_tx_dma, tmp_rx_dma;
1201 dma_addr_t tmp_buf_dma;
1202 int i;
1203
1204 ULI526X_DBUG(0, "uli526x_descriptor_init()", 0);
1205
1206 /* tx descriptor start pointer */
1207 db->tx_insert_ptr = db->first_tx_desc;
1208 db->tx_remove_ptr = db->first_tx_desc;
1209 outl(db->first_tx_desc_dma, ioaddr + DCR4); /* TX DESC address */
1210
1211 /* rx descriptor start pointer */
1212 db->first_rx_desc = (void *)db->first_tx_desc + sizeof(struct tx_desc) * TX_DESC_CNT;
1213 db->first_rx_desc_dma = db->first_tx_desc_dma + sizeof(struct tx_desc) * TX_DESC_CNT;
1214 db->rx_insert_ptr = db->first_rx_desc;
1215 db->rx_ready_ptr = db->first_rx_desc;
1216 outl(db->first_rx_desc_dma, ioaddr + DCR3); /* RX DESC address */
1217
1218 /* Init Transmit chain */
1219 tmp_buf = db->buf_pool_start;
1220 tmp_buf_dma = db->buf_pool_dma_start;
1221 tmp_tx_dma = db->first_tx_desc_dma;
1222 for (tmp_tx = db->first_tx_desc, i = 0; i < TX_DESC_CNT; i++, tmp_tx++) {
1223 tmp_tx->tx_buf_ptr = tmp_buf;
1224 tmp_tx->tdes0 = cpu_to_le32(0);
1225 tmp_tx->tdes1 = cpu_to_le32(0x81000000); /* IC, chain */
1226 tmp_tx->tdes2 = cpu_to_le32(tmp_buf_dma);
1227 tmp_tx_dma += sizeof(struct tx_desc);
1228 tmp_tx->tdes3 = cpu_to_le32(tmp_tx_dma);
1229 tmp_tx->next_tx_desc = tmp_tx + 1;
1230 tmp_buf = tmp_buf + TX_BUF_ALLOC;
1231 tmp_buf_dma = tmp_buf_dma + TX_BUF_ALLOC;
1232 }
1233 (--tmp_tx)->tdes3 = cpu_to_le32(db->first_tx_desc_dma);
1234 tmp_tx->next_tx_desc = db->first_tx_desc;
1235
1236 /* Init Receive descriptor chain */
1237 tmp_rx_dma=db->first_rx_desc_dma;
1238 for (tmp_rx = db->first_rx_desc, i = 0; i < RX_DESC_CNT; i++, tmp_rx++) {
1239 tmp_rx->rdes0 = cpu_to_le32(0);
1240 tmp_rx->rdes1 = cpu_to_le32(0x01000600);
1241 tmp_rx_dma += sizeof(struct rx_desc);
1242 tmp_rx->rdes3 = cpu_to_le32(tmp_rx_dma);
1243 tmp_rx->next_rx_desc = tmp_rx + 1;
1244 }
1245 (--tmp_rx)->rdes3 = cpu_to_le32(db->first_rx_desc_dma);
1246 tmp_rx->next_rx_desc = db->first_rx_desc;
1247
1248 /* pre-allocate Rx buffer */
1249 allocate_rx_buffer(db);
1250}
1251
1252
1253/*
1254 * Update CR6 value
1255 * Firstly stop ULI526X, then written value and start
1256 */
1257
1258static void update_cr6(u32 cr6_data, unsigned long ioaddr)
1259{
1260
1261 outl(cr6_data, ioaddr + DCR6);
1262 udelay(5);
1263}
1264
1265
1266/*
1267 * Send a setup frame for M5261/M5263
1268 * This setup frame initialize ULI526X address filter mode
1269 */
1270
1271static void send_filter_frame(struct net_device *dev, int mc_cnt)
1272{
1273 struct uli526x_board_info *db = netdev_priv(dev);
1274 struct dev_mc_list *mcptr;
1275 struct tx_desc *txptr;
1276 u16 * addrptr;
1277 u32 * suptr;
1278 int i;
1279
1280 ULI526X_DBUG(0, "send_filter_frame()", 0);
1281
1282 txptr = db->tx_insert_ptr;
1283 suptr = (u32 *) txptr->tx_buf_ptr;
1284
1285 /* Node address */
1286 addrptr = (u16 *) dev->dev_addr;
1287 *suptr++ = addrptr[0];
1288 *suptr++ = addrptr[1];
1289 *suptr++ = addrptr[2];
1290
1291 /* broadcast address */
1292 *suptr++ = 0xffff;
1293 *suptr++ = 0xffff;
1294 *suptr++ = 0xffff;
1295
1296 /* fit the multicast address */
1297 for (mcptr = dev->mc_list, i = 0; i < mc_cnt; i++, mcptr = mcptr->next) {
1298 addrptr = (u16 *) mcptr->dmi_addr;
1299 *suptr++ = addrptr[0];
1300 *suptr++ = addrptr[1];
1301 *suptr++ = addrptr[2];
1302 }
1303
1304 for (; i<14; i++) {
1305 *suptr++ = 0xffff;
1306 *suptr++ = 0xffff;
1307 *suptr++ = 0xffff;
1308 }
1309
1310 /* prepare the setup frame */
1311 db->tx_insert_ptr = txptr->next_tx_desc;
1312 txptr->tdes1 = cpu_to_le32(0x890000c0);
1313
1314 /* Resource Check and Send the setup packet */
1315 if (db->tx_packet_cnt < TX_DESC_CNT) {
1316 /* Resource Empty */
1317 db->tx_packet_cnt++;
1318 txptr->tdes0 = cpu_to_le32(0x80000000);
1319 update_cr6(db->cr6_data | 0x2000, dev->base_addr);
1320 outl(0x1, dev->base_addr + DCR1); /* Issue Tx polling */
1321 update_cr6(db->cr6_data, dev->base_addr);
1322 dev->trans_start = jiffies;
1323 } else
1324 printk(KERN_ERR DRV_NAME ": No Tx resource - Send_filter_frame!\n");
1325}
1326
1327
1328/*
1329 * Allocate rx buffer,
1330 * As possible as allocate maxiumn Rx buffer
1331 */
1332
1333static void allocate_rx_buffer(struct uli526x_board_info *db)
1334{
1335 struct rx_desc *rxptr;
1336 struct sk_buff *skb;
1337
1338 rxptr = db->rx_insert_ptr;
1339
1340 while(db->rx_avail_cnt < RX_DESC_CNT) {
1341 if ( ( skb = dev_alloc_skb(RX_ALLOC_SIZE) ) == NULL )
1342 break;
1343 rxptr->rx_skb_ptr = skb; /* FIXME (?) */
1344 rxptr->rdes2 = cpu_to_le32( pci_map_single(db->pdev, skb->tail, RX_ALLOC_SIZE, PCI_DMA_FROMDEVICE) );
1345 wmb();
1346 rxptr->rdes0 = cpu_to_le32(0x80000000);
1347 rxptr = rxptr->next_rx_desc;
1348 db->rx_avail_cnt++;
1349 }
1350
1351 db->rx_insert_ptr = rxptr;
1352}
1353
1354
1355/*
1356 * Read one word data from the serial ROM
1357 */
1358
1359static u16 read_srom_word(long ioaddr, int offset)
1360{
1361 int i;
1362 u16 srom_data = 0;
1363 long cr9_ioaddr = ioaddr + DCR9;
1364
1365 outl(CR9_SROM_READ, cr9_ioaddr);
1366 outl(CR9_SROM_READ | CR9_SRCS, cr9_ioaddr);
1367
1368 /* Send the Read Command 110b */
1369 SROM_CLK_WRITE(SROM_DATA_1, cr9_ioaddr);
1370 SROM_CLK_WRITE(SROM_DATA_1, cr9_ioaddr);
1371 SROM_CLK_WRITE(SROM_DATA_0, cr9_ioaddr);
1372
1373 /* Send the offset */
1374 for (i = 5; i >= 0; i--) {
1375 srom_data = (offset & (1 << i)) ? SROM_DATA_1 : SROM_DATA_0;
1376 SROM_CLK_WRITE(srom_data, cr9_ioaddr);
1377 }
1378
1379 outl(CR9_SROM_READ | CR9_SRCS, cr9_ioaddr);
1380
1381 for (i = 16; i > 0; i--) {
1382 outl(CR9_SROM_READ | CR9_SRCS | CR9_SRCLK, cr9_ioaddr);
1383 udelay(5);
1384 srom_data = (srom_data << 1) | ((inl(cr9_ioaddr) & CR9_CRDOUT) ? 1 : 0);
1385 outl(CR9_SROM_READ | CR9_SRCS, cr9_ioaddr);
1386 udelay(5);
1387 }
1388
1389 outl(CR9_SROM_READ, cr9_ioaddr);
1390 return srom_data;
1391}
1392
1393
1394/*
1395 * Auto sense the media mode
1396 */
1397
1398static u8 uli526x_sense_speed(struct uli526x_board_info * db)
1399{
1400 u8 ErrFlag = 0;
1401 u16 phy_mode;
1402
1403 phy_mode = phy_read(db->ioaddr, db->phy_addr, 1, db->chip_id);
1404 phy_mode = phy_read(db->ioaddr, db->phy_addr, 1, db->chip_id);
1405
1406 if ( (phy_mode & 0x24) == 0x24 ) {
1407
1408 phy_mode = ((phy_read(db->ioaddr, db->phy_addr, 5, db->chip_id) & 0x01e0)<<7);
1409 if(phy_mode&0x8000)
1410 phy_mode = 0x8000;
1411 else if(phy_mode&0x4000)
1412 phy_mode = 0x4000;
1413 else if(phy_mode&0x2000)
1414 phy_mode = 0x2000;
1415 else
1416 phy_mode = 0x1000;
1417
1418 /* printk(DRV_NAME ": Phy_mode %x ",phy_mode); */
1419 switch (phy_mode) {
1420 case 0x1000: db->op_mode = ULI526X_10MHF; break;
1421 case 0x2000: db->op_mode = ULI526X_10MFD; break;
1422 case 0x4000: db->op_mode = ULI526X_100MHF; break;
1423 case 0x8000: db->op_mode = ULI526X_100MFD; break;
1424 default: db->op_mode = ULI526X_10MHF; ErrFlag = 1; break;
1425 }
1426 } else {
1427 db->op_mode = ULI526X_10MHF;
1428 ULI526X_DBUG(0, "Link Failed :", phy_mode);
1429 ErrFlag = 1;
1430 }
1431
1432 return ErrFlag;
1433}
1434
1435
1436/*
1437 * Set 10/100 phyxcer capability
1438 * AUTO mode : phyxcer register4 is NIC capability
1439 * Force mode: phyxcer register4 is the force media
1440 */
1441
1442static void uli526x_set_phyxcer(struct uli526x_board_info *db)
1443{
1444 u16 phy_reg;
1445
1446 /* Phyxcer capability setting */
1447 phy_reg = phy_read(db->ioaddr, db->phy_addr, 4, db->chip_id) & ~0x01e0;
1448
1449 if (db->media_mode & ULI526X_AUTO) {
1450 /* AUTO Mode */
1451 phy_reg |= db->PHY_reg4;
1452 } else {
1453 /* Force Mode */
1454 switch(db->media_mode) {
1455 case ULI526X_10MHF: phy_reg |= 0x20; break;
1456 case ULI526X_10MFD: phy_reg |= 0x40; break;
1457 case ULI526X_100MHF: phy_reg |= 0x80; break;
1458 case ULI526X_100MFD: phy_reg |= 0x100; break;
1459 }
1460
1461 }
1462
1463 /* Write new capability to Phyxcer Reg4 */
1464 if ( !(phy_reg & 0x01e0)) {
1465 phy_reg|=db->PHY_reg4;
1466 db->media_mode|=ULI526X_AUTO;
1467 }
1468 phy_write(db->ioaddr, db->phy_addr, 4, phy_reg, db->chip_id);
1469
1470 /* Restart Auto-Negotiation */
1471 phy_write(db->ioaddr, db->phy_addr, 0, 0x1200, db->chip_id);
1472 udelay(50);
1473}
1474
1475
1476/*
1477 * Process op-mode
1478 AUTO mode : PHY controller in Auto-negotiation Mode
1479 * Force mode: PHY controller in force mode with HUB
1480 * N-way force capability with SWITCH
1481 */
1482
1483static void uli526x_process_mode(struct uli526x_board_info *db)
1484{
1485 u16 phy_reg;
1486
1487 /* Full Duplex Mode Check */
1488 if (db->op_mode & 0x4)
1489 db->cr6_data |= CR6_FDM; /* Set Full Duplex Bit */
1490 else
1491 db->cr6_data &= ~CR6_FDM; /* Clear Full Duplex Bit */
1492
1493 update_cr6(db->cr6_data, db->ioaddr);
1494
1495 /* 10/100M phyxcer force mode need */
1496 if ( !(db->media_mode & 0x8)) {
1497 /* Forece Mode */
1498 phy_reg = phy_read(db->ioaddr, db->phy_addr, 6, db->chip_id);
1499 if ( !(phy_reg & 0x1) ) {
1500 /* parter without N-Way capability */
1501 phy_reg = 0x0;
1502 switch(db->op_mode) {
1503 case ULI526X_10MHF: phy_reg = 0x0; break;
1504 case ULI526X_10MFD: phy_reg = 0x100; break;
1505 case ULI526X_100MHF: phy_reg = 0x2000; break;
1506 case ULI526X_100MFD: phy_reg = 0x2100; break;
1507 }
1508 phy_write(db->ioaddr, db->phy_addr, 0, phy_reg, db->chip_id);
1509 phy_write(db->ioaddr, db->phy_addr, 0, phy_reg, db->chip_id);
1510 }
1511 }
1512}
1513
1514
1515/*
1516 * Write a word to Phy register
1517 */
1518
1519static void phy_write(unsigned long iobase, u8 phy_addr, u8 offset, u16 phy_data, u32 chip_id)
1520{
1521 u16 i;
1522 unsigned long ioaddr;
1523
1524 if(chip_id == PCI_ULI5263_ID)
1525 {
1526 phy_writeby_cr10(iobase, phy_addr, offset, phy_data);
1527 return;
1528 }
1529 /* M5261/M5263 Chip */
1530 ioaddr = iobase + DCR9;
1531
1532 /* Send 33 synchronization clock to Phy controller */
1533 for (i = 0; i < 35; i++)
1534 phy_write_1bit(ioaddr, PHY_DATA_1, chip_id);
1535
1536 /* Send start command(01) to Phy */
1537 phy_write_1bit(ioaddr, PHY_DATA_0, chip_id);
1538 phy_write_1bit(ioaddr, PHY_DATA_1, chip_id);
1539
1540 /* Send write command(01) to Phy */
1541 phy_write_1bit(ioaddr, PHY_DATA_0, chip_id);
1542 phy_write_1bit(ioaddr, PHY_DATA_1, chip_id);
1543
1544 /* Send Phy address */
1545 for (i = 0x10; i > 0; i = i >> 1)
1546 phy_write_1bit(ioaddr, phy_addr & i ? PHY_DATA_1 : PHY_DATA_0, chip_id);
1547
1548 /* Send register address */
1549 for (i = 0x10; i > 0; i = i >> 1)
1550 phy_write_1bit(ioaddr, offset & i ? PHY_DATA_1 : PHY_DATA_0, chip_id);
1551
1552 /* written trasnition */
1553 phy_write_1bit(ioaddr, PHY_DATA_1, chip_id);
1554 phy_write_1bit(ioaddr, PHY_DATA_0, chip_id);
1555
1556 /* Write a word data to PHY controller */
1557 for ( i = 0x8000; i > 0; i >>= 1)
1558 phy_write_1bit(ioaddr, phy_data & i ? PHY_DATA_1 : PHY_DATA_0, chip_id);
1559
1560}
1561
1562
1563/*
1564 * Read a word data from phy register
1565 */
1566
1567static u16 phy_read(unsigned long iobase, u8 phy_addr, u8 offset, u32 chip_id)
1568{
1569 int i;
1570 u16 phy_data;
1571 unsigned long ioaddr;
1572
1573 if(chip_id == PCI_ULI5263_ID)
1574 return phy_readby_cr10(iobase, phy_addr, offset);
1575 /* M5261/M5263 Chip */
1576 ioaddr = iobase + DCR9;
1577
1578 /* Send 33 synchronization clock to Phy controller */
1579 for (i = 0; i < 35; i++)
1580 phy_write_1bit(ioaddr, PHY_DATA_1, chip_id);
1581
1582 /* Send start command(01) to Phy */
1583 phy_write_1bit(ioaddr, PHY_DATA_0, chip_id);
1584 phy_write_1bit(ioaddr, PHY_DATA_1, chip_id);
1585
1586 /* Send read command(10) to Phy */
1587 phy_write_1bit(ioaddr, PHY_DATA_1, chip_id);
1588 phy_write_1bit(ioaddr, PHY_DATA_0, chip_id);
1589
1590 /* Send Phy address */
1591 for (i = 0x10; i > 0; i = i >> 1)
1592 phy_write_1bit(ioaddr, phy_addr & i ? PHY_DATA_1 : PHY_DATA_0, chip_id);
1593
1594 /* Send register address */
1595 for (i = 0x10; i > 0; i = i >> 1)
1596 phy_write_1bit(ioaddr, offset & i ? PHY_DATA_1 : PHY_DATA_0, chip_id);
1597
1598 /* Skip transition state */
1599 phy_read_1bit(ioaddr, chip_id);
1600
1601 /* read 16bit data */
1602 for (phy_data = 0, i = 0; i < 16; i++) {
1603 phy_data <<= 1;
1604 phy_data |= phy_read_1bit(ioaddr, chip_id);
1605 }
1606
1607 return phy_data;
1608}
1609
1610static u16 phy_readby_cr10(unsigned long iobase, u8 phy_addr, u8 offset)
1611{
1612 unsigned long ioaddr,cr10_value;
1613
1614 ioaddr = iobase + DCR10;
1615 cr10_value = phy_addr;
1616 cr10_value = (cr10_value<<5) + offset;
1617 cr10_value = (cr10_value<<16) + 0x08000000;
1618 outl(cr10_value,ioaddr);
1619 udelay(1);
1620 while(1)
1621 {
1622 cr10_value = inl(ioaddr);
1623 if(cr10_value&0x10000000)
1624 break;
1625 }
1626 return (cr10_value&0x0ffff);
1627}
1628
1629static void phy_writeby_cr10(unsigned long iobase, u8 phy_addr, u8 offset, u16 phy_data)
1630{
1631 unsigned long ioaddr,cr10_value;
1632
1633 ioaddr = iobase + DCR10;
1634 cr10_value = phy_addr;
1635 cr10_value = (cr10_value<<5) + offset;
1636 cr10_value = (cr10_value<<16) + 0x04000000 + phy_data;
1637 outl(cr10_value,ioaddr);
1638 udelay(1);
1639}
1640/*
1641 * Write one bit data to Phy Controller
1642 */
1643
1644static void phy_write_1bit(unsigned long ioaddr, u32 phy_data, u32 chip_id)
1645{
1646 outl(phy_data , ioaddr); /* MII Clock Low */
1647 udelay(1);
1648 outl(phy_data | MDCLKH, ioaddr); /* MII Clock High */
1649 udelay(1);
1650 outl(phy_data , ioaddr); /* MII Clock Low */
1651 udelay(1);
1652}
1653
1654
1655/*
1656 * Read one bit phy data from PHY controller
1657 */
1658
1659static u16 phy_read_1bit(unsigned long ioaddr, u32 chip_id)
1660{
1661 u16 phy_data;
1662
1663 outl(0x50000 , ioaddr);
1664 udelay(1);
1665 phy_data = ( inl(ioaddr) >> 19 ) & 0x1;
1666 outl(0x40000 , ioaddr);
1667 udelay(1);
1668
1669 return phy_data;
1670}
1671
1672
1673static struct pci_device_id uli526x_pci_tbl[] = {
1674 { 0x10B9, 0x5261, PCI_ANY_ID, PCI_ANY_ID, 0, 0, PCI_ULI5261_ID },
1675 { 0x10B9, 0x5263, PCI_ANY_ID, PCI_ANY_ID, 0, 0, PCI_ULI5263_ID },
1676 { 0, }
1677};
1678MODULE_DEVICE_TABLE(pci, uli526x_pci_tbl);
1679
1680
1681static struct pci_driver uli526x_driver = {
1682 .name = "uli526x",
1683 .id_table = uli526x_pci_tbl,
1684 .probe = uli526x_init_one,
1685 .remove = __devexit_p(uli526x_remove_one),
1686};
1687
1688MODULE_AUTHOR("Peer Chen, peer.chen@uli.com.tw");
1689MODULE_DESCRIPTION("ULi M5261/M5263 fast ethernet driver");
1690MODULE_LICENSE("GPL");
1691
1692MODULE_PARM(debug, "i");
1693MODULE_PARM(mode, "i");
1694MODULE_PARM(cr6set, "i");
1695MODULE_PARM_DESC(debug, "ULi M5261/M5263 enable debugging (0-1)");
1696MODULE_PARM_DESC(mode, "ULi M5261/M5263: Bit 0: 10/100Mbps, bit 2: duplex, bit 8: HomePNA");
1697
1698/* Description:
1699 * when user used insmod to add module, system invoked init_module()
1700 * to register the services.
1701 */
1702
1703static int __init uli526x_init_module(void)
1704{
1705 int rc;
1706
1707 printk(version);
1708 printed_version = 1;
1709
1710 ULI526X_DBUG(0, "init_module() ", debug);
1711
1712 if (debug)
1713 uli526x_debug = debug; /* set debug flag */
1714 if (cr6set)
1715 uli526x_cr6_user_set = cr6set;
1716
1717 switch(mode) {
1718 case ULI526X_10MHF:
1719 case ULI526X_100MHF:
1720 case ULI526X_10MFD:
1721 case ULI526X_100MFD:
1722 uli526x_media_mode = mode;
1723 break;
1724 default:uli526x_media_mode = ULI526X_AUTO;
1725 break;
1726 }
1727
1728 rc = pci_module_init(&uli526x_driver);
1729 if (rc < 0)
1730 return rc;
1731
1732 return 0;
1733}
1734
1735
1736/*
1737 * Description:
1738 * when user used rmmod to delete module, system invoked clean_module()
1739 * to un-register all registered services.
1740 */
1741
1742static void __exit uli526x_cleanup_module(void)
1743{
1744 ULI526X_DBUG(0, "uli526x_clean_module() ", debug);
1745 pci_unregister_driver(&uli526x_driver);
1746}
1747
1748module_init(uli526x_init_module);
1749module_exit(uli526x_cleanup_module);
diff --git a/drivers/net/wan/hdlc_generic.c b/drivers/net/wan/hdlc_generic.c
index a63f6a2cc4f7..cdd4c09c2d90 100644
--- a/drivers/net/wan/hdlc_generic.c
+++ b/drivers/net/wan/hdlc_generic.c
@@ -61,7 +61,7 @@ static struct net_device_stats *hdlc_get_stats(struct net_device *dev)
61 61
62 62
63static int hdlc_rcv(struct sk_buff *skb, struct net_device *dev, 63static int hdlc_rcv(struct sk_buff *skb, struct net_device *dev,
64 struct packet_type *p) 64 struct packet_type *p, struct net_device *orig_dev)
65{ 65{
66 hdlc_device *hdlc = dev_to_hdlc(dev); 66 hdlc_device *hdlc = dev_to_hdlc(dev);
67 if (hdlc->proto.netif_rx) 67 if (hdlc->proto.netif_rx)
diff --git a/drivers/net/wan/lapbether.c b/drivers/net/wan/lapbether.c
index 7f2e3653c5e5..6c302e9dbca2 100644
--- a/drivers/net/wan/lapbether.c
+++ b/drivers/net/wan/lapbether.c
@@ -86,7 +86,7 @@ static __inline__ int dev_is_ethdev(struct net_device *dev)
86/* 86/*
87 * Receive a LAPB frame via an ethernet interface. 87 * Receive a LAPB frame via an ethernet interface.
88 */ 88 */
89static int lapbeth_rcv(struct sk_buff *skb, struct net_device *dev, struct packet_type *ptype) 89static int lapbeth_rcv(struct sk_buff *skb, struct net_device *dev, struct packet_type *ptype, struct net_device *orig_dev)
90{ 90{
91 int len, err; 91 int len, err;
92 struct lapbethdev *lapbeth; 92 struct lapbethdev *lapbeth;
diff --git a/drivers/net/wan/sdla_fr.c b/drivers/net/wan/sdla_fr.c
index c5f5e62aab8b..0497dbdb8631 100644
--- a/drivers/net/wan/sdla_fr.c
+++ b/drivers/net/wan/sdla_fr.c
@@ -445,7 +445,7 @@ void s508_s514_unlock(sdla_t *card, unsigned long *smp_flags);
445void s508_s514_lock(sdla_t *card, unsigned long *smp_flags); 445void s508_s514_lock(sdla_t *card, unsigned long *smp_flags);
446 446
447unsigned short calc_checksum (char *, int); 447unsigned short calc_checksum (char *, int);
448static int setup_fr_header(struct sk_buff** skb, 448static int setup_fr_header(struct sk_buff *skb,
449 struct net_device* dev, char op_mode); 449 struct net_device* dev, char op_mode);
450 450
451 451
@@ -1372,7 +1372,7 @@ static int if_send(struct sk_buff* skb, struct net_device* dev)
1372 /* Move the if_header() code to here. By inserting frame 1372 /* Move the if_header() code to here. By inserting frame
1373 * relay header in if_header() we would break the 1373 * relay header in if_header() we would break the
1374 * tcpdump and other packet sniffers */ 1374 * tcpdump and other packet sniffers */
1375 chan->fr_header_len = setup_fr_header(&skb,dev,chan->common.usedby); 1375 chan->fr_header_len = setup_fr_header(skb,dev,chan->common.usedby);
1376 if (chan->fr_header_len < 0 ){ 1376 if (chan->fr_header_len < 0 ){
1377 ++chan->ifstats.tx_dropped; 1377 ++chan->ifstats.tx_dropped;
1378 ++card->wandev.stats.tx_dropped; 1378 ++card->wandev.stats.tx_dropped;
@@ -1597,8 +1597,6 @@ static int setup_for_delayed_transmit(struct net_device* dev,
1597 return 1; 1597 return 1;
1598 } 1598 }
1599 1599
1600 skb_unlink(skb);
1601
1602 chan->transmit_length = len; 1600 chan->transmit_length = len;
1603 chan->delay_skb = skb; 1601 chan->delay_skb = skb;
1604 1602
@@ -4871,18 +4869,15 @@ static void unconfig_fr (sdla_t *card)
4871 } 4869 }
4872} 4870}
4873 4871
4874static int setup_fr_header(struct sk_buff **skb_orig, struct net_device* dev, 4872static int setup_fr_header(struct sk_buff *skb, struct net_device* dev,
4875 char op_mode) 4873 char op_mode)
4876{ 4874{
4877 struct sk_buff *skb = *skb_orig;
4878 fr_channel_t *chan=dev->priv; 4875 fr_channel_t *chan=dev->priv;
4879 4876
4880 if (op_mode == WANPIPE){ 4877 if (op_mode == WANPIPE) {
4881
4882 chan->fr_header[0]=Q922_UI; 4878 chan->fr_header[0]=Q922_UI;
4883 4879
4884 switch (htons(skb->protocol)){ 4880 switch (htons(skb->protocol)){
4885
4886 case ETH_P_IP: 4881 case ETH_P_IP:
4887 chan->fr_header[1]=NLPID_IP; 4882 chan->fr_header[1]=NLPID_IP;
4888 break; 4883 break;
@@ -4894,16 +4889,14 @@ static int setup_fr_header(struct sk_buff **skb_orig, struct net_device* dev,
4894 } 4889 }
4895 4890
4896 /* If we are in bridging mode, we must apply 4891 /* If we are in bridging mode, we must apply
4897 * an Ethernet header */ 4892 * an Ethernet header
4898 if (op_mode == BRIDGE || op_mode == BRIDGE_NODE){ 4893 */
4899 4894 if (op_mode == BRIDGE || op_mode == BRIDGE_NODE) {
4900
4901 /* Encapsulate the packet as a bridged Ethernet frame. */ 4895 /* Encapsulate the packet as a bridged Ethernet frame. */
4902#ifdef DEBUG 4896#ifdef DEBUG
4903 printk(KERN_INFO "%s: encapsulating skb for frame relay\n", 4897 printk(KERN_INFO "%s: encapsulating skb for frame relay\n",
4904 dev->name); 4898 dev->name);
4905#endif 4899#endif
4906
4907 chan->fr_header[0] = 0x03; 4900 chan->fr_header[0] = 0x03;
4908 chan->fr_header[1] = 0x00; 4901 chan->fr_header[1] = 0x00;
4909 chan->fr_header[2] = 0x80; 4902 chan->fr_header[2] = 0x80;
@@ -4916,7 +4909,6 @@ static int setup_fr_header(struct sk_buff **skb_orig, struct net_device* dev,
4916 /* Yuck. */ 4909 /* Yuck. */
4917 skb->protocol = ETH_P_802_3; 4910 skb->protocol = ETH_P_802_3;
4918 return 8; 4911 return 8;
4919
4920 } 4912 }
4921 4913
4922 return 0; 4914 return 0;
diff --git a/drivers/net/wan/syncppp.c b/drivers/net/wan/syncppp.c
index 84b65c60c799..f58c794a963a 100644
--- a/drivers/net/wan/syncppp.c
+++ b/drivers/net/wan/syncppp.c
@@ -1447,7 +1447,7 @@ static void sppp_print_bytes (u_char *p, u16 len)
1447 * after interrupt servicing to process frames queued via netif_rx. 1447 * after interrupt servicing to process frames queued via netif_rx.
1448 */ 1448 */
1449 1449
1450static int sppp_rcv(struct sk_buff *skb, struct net_device *dev, struct packet_type *p) 1450static int sppp_rcv(struct sk_buff *skb, struct net_device *dev, struct packet_type *p, struct net_device *orig_dev)
1451{ 1451{
1452 if ((skb = skb_share_check(skb, GFP_ATOMIC)) == NULL) 1452 if ((skb = skb_share_check(skb, GFP_ATOMIC)) == NULL)
1453 return NET_RX_DROP; 1453 return NET_RX_DROP;
diff --git a/drivers/net/wireless/Kconfig b/drivers/net/wireless/Kconfig
index ec3f75a030d2..dd7dbf7b14d4 100644
--- a/drivers/net/wireless/Kconfig
+++ b/drivers/net/wireless/Kconfig
@@ -137,6 +137,110 @@ config PCMCIA_RAYCS
137comment "Wireless 802.11b ISA/PCI cards support" 137comment "Wireless 802.11b ISA/PCI cards support"
138 depends on NET_RADIO && (ISA || PCI || PPC_PMAC || PCMCIA) 138 depends on NET_RADIO && (ISA || PCI || PPC_PMAC || PCMCIA)
139 139
140config IPW2100
141 tristate "Intel PRO/Wireless 2100 Network Connection"
142 depends on NET_RADIO && PCI && IEEE80211
143 select FW_LOADER
144 ---help---
145 A driver for the Intel PRO/Wireless 2100 Network
146 Connection 802.11b wireless network adapter.
147
148 See <file:Documentation/networking/README.ipw2100> for information on
149 the capabilities currently enabled in this driver and for tips
150 for debugging issues and problems.
151
152 In order to use this driver, you will need a firmware image for it.
153 You can obtain the firmware from
154 <http://ipw2100.sf.net/>. Once you have the firmware image, you
155 will need to place it in /etc/firmware.
156
157 You will also very likely need the Wireless Tools in order to
158 configure your card:
159
160 <http://www.hpl.hp.com/personal/Jean_Tourrilhes/Linux/Tools.html>.
161
162 If you want to compile the driver as a module ( = code which can be
163 inserted in and remvoed from the running kernel whenever you want),
164 say M here and read <file:Documentation/modules.txt>. The module
165 will be called ipw2100.ko.
166
167config IPW2100_MONITOR
168 bool "Enable promiscuous mode"
169 depends on IPW2100
170 ---help---
171 Enables promiscuous/monitor mode support for the ipw2100 driver.
172 With this feature compiled into the driver, you can switch to
173 promiscuous mode via the Wireless Tool's Monitor mode. While in this
174 mode, no packets can be sent.
175
176config IPW_DEBUG
177 bool "Enable full debugging output in IPW2100 module."
178 depends on IPW2100
179 ---help---
180 This option will enable debug tracing output for the IPW2100.
181
182 This will result in the kernel module being ~60k larger. You can
183 control which debug output is sent to the kernel log by setting the
184 value in
185
186 /sys/bus/pci/drivers/ipw2100/debug_level
187
188 This entry will only exist if this option is enabled.
189
190 If you are not trying to debug or develop the IPW2100 driver, you
191 most likely want to say N here.
192
193config IPW2200
194 tristate "Intel PRO/Wireless 2200BG and 2915ABG Network Connection"
195 depends on IEEE80211 && PCI
196 select FW_LOADER
197 ---help---
198 A driver for the Intel PRO/Wireless 2200BG and 2915ABG Network
199 Connection adapters.
200
201 See <file:Documentation/networking/README.ipw2200> for
202 information on the capabilities currently enabled in this
203 driver and for tips for debugging issues and problems.
204
205 In order to use this driver, you will need a firmware image for it.
206 You can obtain the firmware from
207 <http://ipw2200.sf.net/>. See the above referenced README.ipw2200
208 for information on where to install the firmare images.
209
210 You will also very likely need the Wireless Tools in order to
211 configure your card:
212
213 <http://www.hpl.hp.com/personal/Jean_Tourrilhes/Linux/Tools.html>.
214
215 If you want to compile the driver as a module ( = code which can be
216 inserted in and remvoed from the running kernel whenever you want),
217 say M here and read <file:Documentation/modules.txt>. The module
218 will be called ipw2200.ko.
219
220config IPW_DEBUG
221 bool "Enable full debugging output in IPW2200 module."
222 depends on IPW2200
223 ---help---
224 This option will enable debug tracing output for the IPW2200.
225
226 This will result in the kernel module being ~100k larger. You can
227 control which debug output is sent to the kernel log by setting the
228 value in
229
230 /sys/bus/pci/drivers/ipw2200/debug_level
231
232 This entry will only exist if this option is enabled.
233
234 To set a value, simply echo an 8-byte hex value to the same file:
235
236 % echo 0x00000FFO > /sys/bus/pci/drivers/ipw2200/debug_level
237
238 You can find the list of debug mask values in
239 drivers/net/wireless/ipw2200.h
240
241 If you are not trying to debug or develop the IPW2200 driver, you
242 most likely want to say N here.
243
140config AIRO 244config AIRO
141 tristate "Cisco/Aironet 34X/35X/4500/4800 ISA and PCI cards" 245 tristate "Cisco/Aironet 34X/35X/4500/4800 ISA and PCI cards"
142 depends on NET_RADIO && ISA && (PCI || BROKEN) 246 depends on NET_RADIO && ISA && (PCI || BROKEN)
@@ -355,6 +459,8 @@ config PRISM54
355 say M here and read <file:Documentation/modules.txt>. The module 459 say M here and read <file:Documentation/modules.txt>. The module
356 will be called prism54.ko. 460 will be called prism54.ko.
357 461
462source "drivers/net/wireless/hostap/Kconfig"
463
358# yes, this works even when no drivers are selected 464# yes, this works even when no drivers are selected
359config NET_WIRELESS 465config NET_WIRELESS
360 bool 466 bool
diff --git a/drivers/net/wireless/Makefile b/drivers/net/wireless/Makefile
index 2b87841322cc..0953cc0cdee6 100644
--- a/drivers/net/wireless/Makefile
+++ b/drivers/net/wireless/Makefile
@@ -2,6 +2,10 @@
2# Makefile for the Linux Wireless network device drivers. 2# Makefile for the Linux Wireless network device drivers.
3# 3#
4 4
5obj-$(CONFIG_IPW2100) += ipw2100.o
6
7obj-$(CONFIG_IPW2200) += ipw2200.o
8
5obj-$(CONFIG_STRIP) += strip.o 9obj-$(CONFIG_STRIP) += strip.o
6obj-$(CONFIG_ARLAN) += arlan.o 10obj-$(CONFIG_ARLAN) += arlan.o
7 11
@@ -28,6 +32,8 @@ obj-$(CONFIG_PCMCIA_ATMEL) += atmel_cs.o
28 32
29obj-$(CONFIG_PRISM54) += prism54/ 33obj-$(CONFIG_PRISM54) += prism54/
30 34
35obj-$(CONFIG_HOSTAP) += hostap/
36
31# 16-bit wireless PCMCIA client drivers 37# 16-bit wireless PCMCIA client drivers
32obj-$(CONFIG_PCMCIA_RAYCS) += ray_cs.o 38obj-$(CONFIG_PCMCIA_RAYCS) += ray_cs.o
33obj-$(CONFIG_PCMCIA_WL3501) += wl3501_cs.o 39obj-$(CONFIG_PCMCIA_WL3501) += wl3501_cs.o
diff --git a/drivers/net/wireless/airo.c b/drivers/net/wireless/airo.c
index df20adcd0730..6db1fb6461de 100644
--- a/drivers/net/wireless/airo.c
+++ b/drivers/net/wireless/airo.c
@@ -1040,7 +1040,7 @@ typedef struct {
1040 u16 status; 1040 u16 status;
1041} WifiCtlHdr; 1041} WifiCtlHdr;
1042 1042
1043WifiCtlHdr wifictlhdr8023 = { 1043static WifiCtlHdr wifictlhdr8023 = {
1044 .ctlhdr = { 1044 .ctlhdr = {
1045 .ctl = HOST_DONT_RLSE, 1045 .ctl = HOST_DONT_RLSE,
1046 } 1046 }
@@ -1111,13 +1111,13 @@ static int airo_thread(void *data);
1111static void timer_func( struct net_device *dev ); 1111static void timer_func( struct net_device *dev );
1112static int airo_ioctl(struct net_device *dev, struct ifreq *rq, int cmd); 1112static int airo_ioctl(struct net_device *dev, struct ifreq *rq, int cmd);
1113#ifdef WIRELESS_EXT 1113#ifdef WIRELESS_EXT
1114struct iw_statistics *airo_get_wireless_stats (struct net_device *dev); 1114static struct iw_statistics *airo_get_wireless_stats (struct net_device *dev);
1115static void airo_read_wireless_stats (struct airo_info *local); 1115static void airo_read_wireless_stats (struct airo_info *local);
1116#endif /* WIRELESS_EXT */ 1116#endif /* WIRELESS_EXT */
1117#ifdef CISCO_EXT 1117#ifdef CISCO_EXT
1118static int readrids(struct net_device *dev, aironet_ioctl *comp); 1118static int readrids(struct net_device *dev, aironet_ioctl *comp);
1119static int writerids(struct net_device *dev, aironet_ioctl *comp); 1119static int writerids(struct net_device *dev, aironet_ioctl *comp);
1120int flashcard(struct net_device *dev, aironet_ioctl *comp); 1120static int flashcard(struct net_device *dev, aironet_ioctl *comp);
1121#endif /* CISCO_EXT */ 1121#endif /* CISCO_EXT */
1122#ifdef MICSUPPORT 1122#ifdef MICSUPPORT
1123static void micinit(struct airo_info *ai); 1123static void micinit(struct airo_info *ai);
@@ -1226,6 +1226,12 @@ static int setup_proc_entry( struct net_device *dev,
1226static int takedown_proc_entry( struct net_device *dev, 1226static int takedown_proc_entry( struct net_device *dev,
1227 struct airo_info *apriv ); 1227 struct airo_info *apriv );
1228 1228
1229static int cmdreset(struct airo_info *ai);
1230static int setflashmode (struct airo_info *ai);
1231static int flashgchar(struct airo_info *ai,int matchbyte,int dwelltime);
1232static int flashputbuf(struct airo_info *ai);
1233static int flashrestart(struct airo_info *ai,struct net_device *dev);
1234
1229#ifdef MICSUPPORT 1235#ifdef MICSUPPORT
1230/*********************************************************************** 1236/***********************************************************************
1231 * MIC ROUTINES * 1237 * MIC ROUTINES *
@@ -1234,10 +1240,11 @@ static int takedown_proc_entry( struct net_device *dev,
1234 1240
1235static int RxSeqValid (struct airo_info *ai,miccntx *context,int mcast,u32 micSeq); 1241static int RxSeqValid (struct airo_info *ai,miccntx *context,int mcast,u32 micSeq);
1236static void MoveWindow(miccntx *context, u32 micSeq); 1242static void MoveWindow(miccntx *context, u32 micSeq);
1237void emmh32_setseed(emmh32_context *context, u8 *pkey, int keylen, struct crypto_tfm *); 1243static void emmh32_setseed(emmh32_context *context, u8 *pkey, int keylen, struct crypto_tfm *);
1238void emmh32_init(emmh32_context *context); 1244static void emmh32_init(emmh32_context *context);
1239void emmh32_update(emmh32_context *context, u8 *pOctets, int len); 1245static void emmh32_update(emmh32_context *context, u8 *pOctets, int len);
1240void emmh32_final(emmh32_context *context, u8 digest[4]); 1246static void emmh32_final(emmh32_context *context, u8 digest[4]);
1247static int flashpchar(struct airo_info *ai,int byte,int dwelltime);
1241 1248
1242/* micinit - Initialize mic seed */ 1249/* micinit - Initialize mic seed */
1243 1250
@@ -1315,7 +1322,7 @@ static int micsetup(struct airo_info *ai) {
1315 return SUCCESS; 1322 return SUCCESS;
1316} 1323}
1317 1324
1318char micsnap[]= {0xAA,0xAA,0x03,0x00,0x40,0x96,0x00,0x02}; 1325static char micsnap[] = {0xAA,0xAA,0x03,0x00,0x40,0x96,0x00,0x02};
1319 1326
1320/*=========================================================================== 1327/*===========================================================================
1321 * Description: Mic a packet 1328 * Description: Mic a packet
@@ -1570,7 +1577,7 @@ static void MoveWindow(miccntx *context, u32 micSeq)
1570static unsigned char aes_counter[16]; 1577static unsigned char aes_counter[16];
1571 1578
1572/* expand the key to fill the MMH coefficient array */ 1579/* expand the key to fill the MMH coefficient array */
1573void emmh32_setseed(emmh32_context *context, u8 *pkey, int keylen, struct crypto_tfm *tfm) 1580static void emmh32_setseed(emmh32_context *context, u8 *pkey, int keylen, struct crypto_tfm *tfm)
1574{ 1581{
1575 /* take the keying material, expand if necessary, truncate at 16-bytes */ 1582 /* take the keying material, expand if necessary, truncate at 16-bytes */
1576 /* run through AES counter mode to generate context->coeff[] */ 1583 /* run through AES counter mode to generate context->coeff[] */
@@ -1602,7 +1609,7 @@ void emmh32_setseed(emmh32_context *context, u8 *pkey, int keylen, struct crypto
1602} 1609}
1603 1610
1604/* prepare for calculation of a new mic */ 1611/* prepare for calculation of a new mic */
1605void emmh32_init(emmh32_context *context) 1612static void emmh32_init(emmh32_context *context)
1606{ 1613{
1607 /* prepare for new mic calculation */ 1614 /* prepare for new mic calculation */
1608 context->accum = 0; 1615 context->accum = 0;
@@ -1610,7 +1617,7 @@ void emmh32_init(emmh32_context *context)
1610} 1617}
1611 1618
1612/* add some bytes to the mic calculation */ 1619/* add some bytes to the mic calculation */
1613void emmh32_update(emmh32_context *context, u8 *pOctets, int len) 1620static void emmh32_update(emmh32_context *context, u8 *pOctets, int len)
1614{ 1621{
1615 int coeff_position, byte_position; 1622 int coeff_position, byte_position;
1616 1623
@@ -1652,7 +1659,7 @@ void emmh32_update(emmh32_context *context, u8 *pOctets, int len)
1652static u32 mask32[4] = { 0x00000000L, 0xFF000000L, 0xFFFF0000L, 0xFFFFFF00L }; 1659static u32 mask32[4] = { 0x00000000L, 0xFF000000L, 0xFFFF0000L, 0xFFFFFF00L };
1653 1660
1654/* calculate the mic */ 1661/* calculate the mic */
1655void emmh32_final(emmh32_context *context, u8 digest[4]) 1662static void emmh32_final(emmh32_context *context, u8 digest[4])
1656{ 1663{
1657 int coeff_position, byte_position; 1664 int coeff_position, byte_position;
1658 u32 val; 1665 u32 val;
@@ -2255,7 +2262,7 @@ static void airo_read_stats(struct airo_info *ai) {
2255 ai->stats.rx_fifo_errors = vals[0]; 2262 ai->stats.rx_fifo_errors = vals[0];
2256} 2263}
2257 2264
2258struct net_device_stats *airo_get_stats(struct net_device *dev) 2265static struct net_device_stats *airo_get_stats(struct net_device *dev)
2259{ 2266{
2260 struct airo_info *local = dev->priv; 2267 struct airo_info *local = dev->priv;
2261 2268
@@ -2414,7 +2421,7 @@ EXPORT_SYMBOL(stop_airo_card);
2414 2421
2415static int add_airo_dev( struct net_device *dev ); 2422static int add_airo_dev( struct net_device *dev );
2416 2423
2417int wll_header_parse(struct sk_buff *skb, unsigned char *haddr) 2424static int wll_header_parse(struct sk_buff *skb, unsigned char *haddr)
2418{ 2425{
2419 memcpy(haddr, skb->mac.raw + 10, ETH_ALEN); 2426 memcpy(haddr, skb->mac.raw + 10, ETH_ALEN);
2420 return ETH_ALEN; 2427 return ETH_ALEN;
@@ -2681,7 +2688,7 @@ static struct net_device *init_wifidev(struct airo_info *ai,
2681 return dev; 2688 return dev;
2682} 2689}
2683 2690
2684int reset_card( struct net_device *dev , int lock) { 2691static int reset_card( struct net_device *dev , int lock) {
2685 struct airo_info *ai = dev->priv; 2692 struct airo_info *ai = dev->priv;
2686 2693
2687 if (lock && down_interruptible(&ai->sem)) 2694 if (lock && down_interruptible(&ai->sem))
@@ -2696,9 +2703,9 @@ int reset_card( struct net_device *dev , int lock) {
2696 return 0; 2703 return 0;
2697} 2704}
2698 2705
2699struct net_device *_init_airo_card( unsigned short irq, int port, 2706static struct net_device *_init_airo_card( unsigned short irq, int port,
2700 int is_pcmcia, struct pci_dev *pci, 2707 int is_pcmcia, struct pci_dev *pci,
2701 struct device *dmdev ) 2708 struct device *dmdev )
2702{ 2709{
2703 struct net_device *dev; 2710 struct net_device *dev;
2704 struct airo_info *ai; 2711 struct airo_info *ai;
@@ -7235,7 +7242,7 @@ static void airo_read_wireless_stats(struct airo_info *local)
7235 local->wstats.miss.beacon = vals[34]; 7242 local->wstats.miss.beacon = vals[34];
7236} 7243}
7237 7244
7238struct iw_statistics *airo_get_wireless_stats(struct net_device *dev) 7245static struct iw_statistics *airo_get_wireless_stats(struct net_device *dev)
7239{ 7246{
7240 struct airo_info *local = dev->priv; 7247 struct airo_info *local = dev->priv;
7241 7248
@@ -7450,14 +7457,8 @@ static int writerids(struct net_device *dev, aironet_ioctl *comp) {
7450 * Flash command switch table 7457 * Flash command switch table
7451 */ 7458 */
7452 7459
7453int flashcard(struct net_device *dev, aironet_ioctl *comp) { 7460static int flashcard(struct net_device *dev, aironet_ioctl *comp) {
7454 int z; 7461 int z;
7455 int cmdreset(struct airo_info *);
7456 int setflashmode(struct airo_info *);
7457 int flashgchar(struct airo_info *,int,int);
7458 int flashpchar(struct airo_info *,int,int);
7459 int flashputbuf(struct airo_info *);
7460 int flashrestart(struct airo_info *,struct net_device *);
7461 7462
7462 /* Only super-user can modify flash */ 7463 /* Only super-user can modify flash */
7463 if (!capable(CAP_NET_ADMIN)) 7464 if (!capable(CAP_NET_ADMIN))
@@ -7515,7 +7516,7 @@ int flashcard(struct net_device *dev, aironet_ioctl *comp) {
7515 * card. 7516 * card.
7516 */ 7517 */
7517 7518
7518int cmdreset(struct airo_info *ai) { 7519static int cmdreset(struct airo_info *ai) {
7519 disable_MAC(ai, 1); 7520 disable_MAC(ai, 1);
7520 7521
7521 if(!waitbusy (ai)){ 7522 if(!waitbusy (ai)){
@@ -7539,7 +7540,7 @@ int cmdreset(struct airo_info *ai) {
7539 * mode 7540 * mode
7540 */ 7541 */
7541 7542
7542int setflashmode (struct airo_info *ai) { 7543static int setflashmode (struct airo_info *ai) {
7543 set_bit (FLAG_FLASHING, &ai->flags); 7544 set_bit (FLAG_FLASHING, &ai->flags);
7544 7545
7545 OUT4500(ai, SWS0, FLASH_COMMAND); 7546 OUT4500(ai, SWS0, FLASH_COMMAND);
@@ -7566,7 +7567,7 @@ int setflashmode (struct airo_info *ai) {
7566 * x 50us for echo . 7567 * x 50us for echo .
7567 */ 7568 */
7568 7569
7569int flashpchar(struct airo_info *ai,int byte,int dwelltime) { 7570static int flashpchar(struct airo_info *ai,int byte,int dwelltime) {
7570 int echo; 7571 int echo;
7571 int waittime; 7572 int waittime;
7572 7573
@@ -7606,7 +7607,7 @@ int flashpchar(struct airo_info *ai,int byte,int dwelltime) {
7606 * Get a character from the card matching matchbyte 7607 * Get a character from the card matching matchbyte
7607 * Step 3) 7608 * Step 3)
7608 */ 7609 */
7609int flashgchar(struct airo_info *ai,int matchbyte,int dwelltime){ 7610static int flashgchar(struct airo_info *ai,int matchbyte,int dwelltime){
7610 int rchar; 7611 int rchar;
7611 unsigned char rbyte=0; 7612 unsigned char rbyte=0;
7612 7613
@@ -7637,7 +7638,7 @@ int flashgchar(struct airo_info *ai,int matchbyte,int dwelltime){
7637 * send to the card 7638 * send to the card
7638 */ 7639 */
7639 7640
7640int flashputbuf(struct airo_info *ai){ 7641static int flashputbuf(struct airo_info *ai){
7641 int nwords; 7642 int nwords;
7642 7643
7643 /* Write stuff */ 7644 /* Write stuff */
@@ -7659,7 +7660,7 @@ int flashputbuf(struct airo_info *ai){
7659/* 7660/*
7660 * 7661 *
7661 */ 7662 */
7662int flashrestart(struct airo_info *ai,struct net_device *dev){ 7663static int flashrestart(struct airo_info *ai,struct net_device *dev){
7663 int i,status; 7664 int i,status;
7664 7665
7665 ssleep(1); /* Added 12/7/00 */ 7666 ssleep(1); /* Added 12/7/00 */
diff --git a/drivers/net/wireless/atmel.c b/drivers/net/wireless/atmel.c
index 18a7d38d2a13..f48a6e729224 100644
--- a/drivers/net/wireless/atmel.c
+++ b/drivers/net/wireless/atmel.c
@@ -68,7 +68,7 @@
68#include <linux/device.h> 68#include <linux/device.h>
69#include <linux/moduleparam.h> 69#include <linux/moduleparam.h>
70#include <linux/firmware.h> 70#include <linux/firmware.h>
71#include "ieee802_11.h" 71#include <net/ieee80211.h>
72#include "atmel.h" 72#include "atmel.h"
73 73
74#define DRIVER_MAJOR 0 74#define DRIVER_MAJOR 0
@@ -618,12 +618,12 @@ static int atmel_lock_mac(struct atmel_private *priv);
618static void atmel_wmem32(struct atmel_private *priv, u16 pos, u32 data); 618static void atmel_wmem32(struct atmel_private *priv, u16 pos, u32 data);
619static void atmel_command_irq(struct atmel_private *priv); 619static void atmel_command_irq(struct atmel_private *priv);
620static int atmel_validate_channel(struct atmel_private *priv, int channel); 620static int atmel_validate_channel(struct atmel_private *priv, int channel);
621static void atmel_management_frame(struct atmel_private *priv, struct ieee802_11_hdr *header, 621static void atmel_management_frame(struct atmel_private *priv, struct ieee80211_hdr *header,
622 u16 frame_len, u8 rssi); 622 u16 frame_len, u8 rssi);
623static void atmel_management_timer(u_long a); 623static void atmel_management_timer(u_long a);
624static void atmel_send_command(struct atmel_private *priv, int command, void *cmd, int cmd_size); 624static void atmel_send_command(struct atmel_private *priv, int command, void *cmd, int cmd_size);
625static int atmel_send_command_wait(struct atmel_private *priv, int command, void *cmd, int cmd_size); 625static int atmel_send_command_wait(struct atmel_private *priv, int command, void *cmd, int cmd_size);
626static void atmel_transmit_management_frame(struct atmel_private *priv, struct ieee802_11_hdr *header, 626static void atmel_transmit_management_frame(struct atmel_private *priv, struct ieee80211_hdr *header,
627 u8 *body, int body_len); 627 u8 *body, int body_len);
628 628
629static u8 atmel_get_mib8(struct atmel_private *priv, u8 type, u8 index); 629static u8 atmel_get_mib8(struct atmel_private *priv, u8 type, u8 index);
@@ -827,7 +827,7 @@ static void tx_update_descriptor(struct atmel_private *priv, int is_bcast, u16 l
827static int start_tx (struct sk_buff *skb, struct net_device *dev) 827static int start_tx (struct sk_buff *skb, struct net_device *dev)
828{ 828{
829 struct atmel_private *priv = netdev_priv(dev); 829 struct atmel_private *priv = netdev_priv(dev);
830 struct ieee802_11_hdr header; 830 struct ieee80211_hdr header;
831 unsigned long flags; 831 unsigned long flags;
832 u16 buff, frame_ctl, len = (ETH_ZLEN < skb->len) ? skb->len : ETH_ZLEN; 832 u16 buff, frame_ctl, len = (ETH_ZLEN < skb->len) ? skb->len : ETH_ZLEN;
833 u8 SNAP_RFC1024[6] = {0xaa, 0xaa, 0x03, 0x00, 0x00, 0x00}; 833 u8 SNAP_RFC1024[6] = {0xaa, 0xaa, 0x03, 0x00, 0x00, 0x00};
@@ -863,17 +863,17 @@ static int start_tx (struct sk_buff *skb, struct net_device *dev)
863 return 1; 863 return 1;
864 } 864 }
865 865
866 frame_ctl = IEEE802_11_FTYPE_DATA; 866 frame_ctl = IEEE80211_FTYPE_DATA;
867 header.duration_id = 0; 867 header.duration_id = 0;
868 header.seq_ctl = 0; 868 header.seq_ctl = 0;
869 if (priv->wep_is_on) 869 if (priv->wep_is_on)
870 frame_ctl |= IEEE802_11_FCTL_WEP; 870 frame_ctl |= IEEE80211_FCTL_PROTECTED;
871 if (priv->operating_mode == IW_MODE_ADHOC) { 871 if (priv->operating_mode == IW_MODE_ADHOC) {
872 memcpy(&header.addr1, skb->data, 6); 872 memcpy(&header.addr1, skb->data, 6);
873 memcpy(&header.addr2, dev->dev_addr, 6); 873 memcpy(&header.addr2, dev->dev_addr, 6);
874 memcpy(&header.addr3, priv->BSSID, 6); 874 memcpy(&header.addr3, priv->BSSID, 6);
875 } else { 875 } else {
876 frame_ctl |= IEEE802_11_FCTL_TODS; 876 frame_ctl |= IEEE80211_FCTL_TODS;
877 memcpy(&header.addr1, priv->CurrentBSSID, 6); 877 memcpy(&header.addr1, priv->CurrentBSSID, 6);
878 memcpy(&header.addr2, dev->dev_addr, 6); 878 memcpy(&header.addr2, dev->dev_addr, 6);
879 memcpy(&header.addr3, skb->data, 6); 879 memcpy(&header.addr3, skb->data, 6);
@@ -902,7 +902,7 @@ static int start_tx (struct sk_buff *skb, struct net_device *dev)
902} 902}
903 903
904static void atmel_transmit_management_frame(struct atmel_private *priv, 904static void atmel_transmit_management_frame(struct atmel_private *priv,
905 struct ieee802_11_hdr *header, 905 struct ieee80211_hdr *header,
906 u8 *body, int body_len) 906 u8 *body, int body_len)
907{ 907{
908 u16 buff; 908 u16 buff;
@@ -917,7 +917,7 @@ static void atmel_transmit_management_frame(struct atmel_private *priv,
917 tx_update_descriptor(priv, header->addr1[0] & 0x01, len, buff, TX_PACKET_TYPE_MGMT); 917 tx_update_descriptor(priv, header->addr1[0] & 0x01, len, buff, TX_PACKET_TYPE_MGMT);
918} 918}
919 919
920static void fast_rx_path(struct atmel_private *priv, struct ieee802_11_hdr *header, 920static void fast_rx_path(struct atmel_private *priv, struct ieee80211_hdr *header,
921 u16 msdu_size, u16 rx_packet_loc, u32 crc) 921 u16 msdu_size, u16 rx_packet_loc, u32 crc)
922{ 922{
923 /* fast path: unfragmented packet copy directly into skbuf */ 923 /* fast path: unfragmented packet copy directly into skbuf */
@@ -955,7 +955,7 @@ static void fast_rx_path(struct atmel_private *priv, struct ieee802_11_hdr *head
955 } 955 }
956 956
957 memcpy(skbp, header->addr1, 6); /* destination address */ 957 memcpy(skbp, header->addr1, 6); /* destination address */
958 if (le16_to_cpu(header->frame_ctl) & IEEE802_11_FCTL_FROMDS) 958 if (le16_to_cpu(header->frame_ctl) & IEEE80211_FCTL_FROMDS)
959 memcpy(&skbp[6], header->addr3, 6); 959 memcpy(&skbp[6], header->addr3, 6);
960 else 960 else
961 memcpy(&skbp[6], header->addr2, 6); /* source address */ 961 memcpy(&skbp[6], header->addr2, 6); /* source address */
@@ -990,14 +990,14 @@ static int probe_crc(struct atmel_private *priv, u16 packet_loc, u16 msdu_size)
990 return (crc ^ 0xffffffff) == netcrc; 990 return (crc ^ 0xffffffff) == netcrc;
991} 991}
992 992
993static void frag_rx_path(struct atmel_private *priv, struct ieee802_11_hdr *header, 993static void frag_rx_path(struct atmel_private *priv, struct ieee80211_hdr *header,
994 u16 msdu_size, u16 rx_packet_loc, u32 crc, u16 seq_no, u8 frag_no, int more_frags) 994 u16 msdu_size, u16 rx_packet_loc, u32 crc, u16 seq_no, u8 frag_no, int more_frags)
995{ 995{
996 u8 mac4[6]; 996 u8 mac4[6];
997 u8 source[6]; 997 u8 source[6];
998 struct sk_buff *skb; 998 struct sk_buff *skb;
999 999
1000 if (le16_to_cpu(header->frame_ctl) & IEEE802_11_FCTL_FROMDS) 1000 if (le16_to_cpu(header->frame_ctl) & IEEE80211_FCTL_FROMDS)
1001 memcpy(source, header->addr3, 6); 1001 memcpy(source, header->addr3, 6);
1002 else 1002 else
1003 memcpy(source, header->addr2, 6); 1003 memcpy(source, header->addr2, 6);
@@ -1082,7 +1082,7 @@ static void frag_rx_path(struct atmel_private *priv, struct ieee802_11_hdr *head
1082static void rx_done_irq(struct atmel_private *priv) 1082static void rx_done_irq(struct atmel_private *priv)
1083{ 1083{
1084 int i; 1084 int i;
1085 struct ieee802_11_hdr header; 1085 struct ieee80211_hdr header;
1086 1086
1087 for (i = 0; 1087 for (i = 0;
1088 atmel_rmem8(priv, atmel_rx(priv, RX_DESC_FLAGS_OFFSET, priv->rx_desc_head)) == RX_DESC_FLAG_VALID && 1088 atmel_rmem8(priv, atmel_rx(priv, RX_DESC_FLAGS_OFFSET, priv->rx_desc_head)) == RX_DESC_FLAG_VALID &&
@@ -1117,7 +1117,7 @@ static void rx_done_irq(struct atmel_private *priv)
1117 /* probe for CRC use here if needed once five packets have arrived with 1117 /* probe for CRC use here if needed once five packets have arrived with
1118 the same crc status, we assume we know what's happening and stop probing */ 1118 the same crc status, we assume we know what's happening and stop probing */
1119 if (priv->probe_crc) { 1119 if (priv->probe_crc) {
1120 if (!priv->wep_is_on || !(frame_ctl & IEEE802_11_FCTL_WEP)) { 1120 if (!priv->wep_is_on || !(frame_ctl & IEEE80211_FCTL_PROTECTED)) {
1121 priv->do_rx_crc = probe_crc(priv, rx_packet_loc, msdu_size); 1121 priv->do_rx_crc = probe_crc(priv, rx_packet_loc, msdu_size);
1122 } else { 1122 } else {
1123 priv->do_rx_crc = probe_crc(priv, rx_packet_loc + 24, msdu_size - 24); 1123 priv->do_rx_crc = probe_crc(priv, rx_packet_loc + 24, msdu_size - 24);
@@ -1132,16 +1132,16 @@ static void rx_done_irq(struct atmel_private *priv)
1132 } 1132 }
1133 1133
1134 /* don't CRC header when WEP in use */ 1134 /* don't CRC header when WEP in use */
1135 if (priv->do_rx_crc && (!priv->wep_is_on || !(frame_ctl & IEEE802_11_FCTL_WEP))) { 1135 if (priv->do_rx_crc && (!priv->wep_is_on || !(frame_ctl & IEEE80211_FCTL_PROTECTED))) {
1136 crc = crc32_le(0xffffffff, (unsigned char *)&header, 24); 1136 crc = crc32_le(0xffffffff, (unsigned char *)&header, 24);
1137 } 1137 }
1138 msdu_size -= 24; /* header */ 1138 msdu_size -= 24; /* header */
1139 1139
1140 if ((frame_ctl & IEEE802_11_FCTL_FTYPE) == IEEE802_11_FTYPE_DATA) { 1140 if ((frame_ctl & IEEE80211_FCTL_FTYPE) == IEEE80211_FTYPE_DATA) {
1141 1141
1142 int more_fragments = frame_ctl & IEEE802_11_FCTL_MOREFRAGS; 1142 int more_fragments = frame_ctl & IEEE80211_FCTL_MOREFRAGS;
1143 u8 packet_fragment_no = seq_control & IEEE802_11_SCTL_FRAG; 1143 u8 packet_fragment_no = seq_control & IEEE80211_SCTL_FRAG;
1144 u16 packet_sequence_no = (seq_control & IEEE802_11_SCTL_SEQ) >> 4; 1144 u16 packet_sequence_no = (seq_control & IEEE80211_SCTL_SEQ) >> 4;
1145 1145
1146 if (!more_fragments && packet_fragment_no == 0 ) { 1146 if (!more_fragments && packet_fragment_no == 0 ) {
1147 fast_rx_path(priv, &header, msdu_size, rx_packet_loc, crc); 1147 fast_rx_path(priv, &header, msdu_size, rx_packet_loc, crc);
@@ -1151,7 +1151,7 @@ static void rx_done_irq(struct atmel_private *priv)
1151 } 1151 }
1152 } 1152 }
1153 1153
1154 if ((frame_ctl & IEEE802_11_FCTL_FTYPE) == IEEE802_11_FTYPE_MGMT) { 1154 if ((frame_ctl & IEEE80211_FCTL_FTYPE) == IEEE80211_FTYPE_MGMT) {
1155 /* copy rest of packet into buffer */ 1155 /* copy rest of packet into buffer */
1156 atmel_copy_to_host(priv->dev, (unsigned char *)&priv->rx_buf, rx_packet_loc + 24, msdu_size); 1156 atmel_copy_to_host(priv->dev, (unsigned char *)&priv->rx_buf, rx_packet_loc + 24, msdu_size);
1157 1157
@@ -2663,10 +2663,10 @@ static void handle_beacon_probe(struct atmel_private *priv, u16 capability, u8 c
2663 2663
2664static void send_authentication_request(struct atmel_private *priv, u8 *challenge, int challenge_len) 2664static void send_authentication_request(struct atmel_private *priv, u8 *challenge, int challenge_len)
2665{ 2665{
2666 struct ieee802_11_hdr header; 2666 struct ieee80211_hdr header;
2667 struct auth_body auth; 2667 struct auth_body auth;
2668 2668
2669 header.frame_ctl = cpu_to_le16(IEEE802_11_FTYPE_MGMT | IEEE802_11_STYPE_AUTH); 2669 header.frame_ctl = cpu_to_le16(IEEE80211_FTYPE_MGMT | IEEE80211_STYPE_AUTH);
2670 header.duration_id = cpu_to_le16(0x8000); 2670 header.duration_id = cpu_to_le16(0x8000);
2671 header.seq_ctl = 0; 2671 header.seq_ctl = 0;
2672 memcpy(header.addr1, priv->CurrentBSSID, 6); 2672 memcpy(header.addr1, priv->CurrentBSSID, 6);
@@ -2677,7 +2677,7 @@ static void send_authentication_request(struct atmel_private *priv, u8 *challeng
2677 auth.alg = cpu_to_le16(C80211_MGMT_AAN_SHAREDKEY); 2677 auth.alg = cpu_to_le16(C80211_MGMT_AAN_SHAREDKEY);
2678 /* no WEP for authentication frames with TrSeqNo 1 */ 2678 /* no WEP for authentication frames with TrSeqNo 1 */
2679 if (priv->CurrentAuthentTransactionSeqNum != 1) 2679 if (priv->CurrentAuthentTransactionSeqNum != 1)
2680 header.frame_ctl |= cpu_to_le16(IEEE802_11_FCTL_WEP); 2680 header.frame_ctl |= cpu_to_le16(IEEE80211_FCTL_PROTECTED);
2681 } else { 2681 } else {
2682 auth.alg = cpu_to_le16(C80211_MGMT_AAN_OPENSYSTEM); 2682 auth.alg = cpu_to_le16(C80211_MGMT_AAN_OPENSYSTEM);
2683 } 2683 }
@@ -2701,7 +2701,7 @@ static void send_association_request(struct atmel_private *priv, int is_reassoc)
2701{ 2701{
2702 u8 *ssid_el_p; 2702 u8 *ssid_el_p;
2703 int bodysize; 2703 int bodysize;
2704 struct ieee802_11_hdr header; 2704 struct ieee80211_hdr header;
2705 struct ass_req_format { 2705 struct ass_req_format {
2706 u16 capability; 2706 u16 capability;
2707 u16 listen_interval; 2707 u16 listen_interval;
@@ -2714,8 +2714,8 @@ static void send_association_request(struct atmel_private *priv, int is_reassoc)
2714 u8 rates[4]; 2714 u8 rates[4];
2715 } body; 2715 } body;
2716 2716
2717 header.frame_ctl = cpu_to_le16(IEEE802_11_FTYPE_MGMT | 2717 header.frame_ctl = cpu_to_le16(IEEE80211_FTYPE_MGMT |
2718 (is_reassoc ? IEEE802_11_STYPE_REASSOC_REQ : IEEE802_11_STYPE_ASSOC_REQ)); 2718 (is_reassoc ? IEEE80211_STYPE_REASSOC_REQ : IEEE80211_STYPE_ASSOC_REQ));
2719 header.duration_id = cpu_to_le16(0x8000); 2719 header.duration_id = cpu_to_le16(0x8000);
2720 header.seq_ctl = 0; 2720 header.seq_ctl = 0;
2721 2721
@@ -2751,9 +2751,9 @@ static void send_association_request(struct atmel_private *priv, int is_reassoc)
2751 atmel_transmit_management_frame(priv, &header, (void *)&body, bodysize); 2751 atmel_transmit_management_frame(priv, &header, (void *)&body, bodysize);
2752} 2752}
2753 2753
2754static int is_frame_from_current_bss(struct atmel_private *priv, struct ieee802_11_hdr *header) 2754static int is_frame_from_current_bss(struct atmel_private *priv, struct ieee80211_hdr *header)
2755{ 2755{
2756 if (le16_to_cpu(header->frame_ctl) & IEEE802_11_FCTL_FROMDS) 2756 if (le16_to_cpu(header->frame_ctl) & IEEE80211_FCTL_FROMDS)
2757 return memcmp(header->addr3, priv->CurrentBSSID, 6) == 0; 2757 return memcmp(header->addr3, priv->CurrentBSSID, 6) == 0;
2758 else 2758 else
2759 return memcmp(header->addr2, priv->CurrentBSSID, 6) == 0; 2759 return memcmp(header->addr2, priv->CurrentBSSID, 6) == 0;
@@ -2801,7 +2801,7 @@ static int retrieve_bss(struct atmel_private *priv)
2801} 2801}
2802 2802
2803 2803
2804static void store_bss_info(struct atmel_private *priv, struct ieee802_11_hdr *header, 2804static void store_bss_info(struct atmel_private *priv, struct ieee80211_hdr *header,
2805 u16 capability, u16 beacon_period, u8 channel, u8 rssi, 2805 u16 capability, u16 beacon_period, u8 channel, u8 rssi,
2806 u8 ssid_len, u8 *ssid, int is_beacon) 2806 u8 ssid_len, u8 *ssid, int is_beacon)
2807{ 2807{
@@ -3085,12 +3085,12 @@ static void atmel_smooth_qual(struct atmel_private *priv)
3085} 3085}
3086 3086
3087/* deals with incoming managment frames. */ 3087/* deals with incoming managment frames. */
3088static void atmel_management_frame(struct atmel_private *priv, struct ieee802_11_hdr *header, 3088static void atmel_management_frame(struct atmel_private *priv, struct ieee80211_hdr *header,
3089 u16 frame_len, u8 rssi) 3089 u16 frame_len, u8 rssi)
3090{ 3090{
3091 u16 subtype; 3091 u16 subtype;
3092 3092
3093 switch (subtype = le16_to_cpu(header->frame_ctl) & IEEE802_11_FCTL_STYPE) { 3093 switch (subtype = le16_to_cpu(header->frame_ctl) & IEEE80211_FCTL_STYPE) {
3094 case C80211_SUBTYPE_MGMT_BEACON : 3094 case C80211_SUBTYPE_MGMT_BEACON :
3095 case C80211_SUBTYPE_MGMT_ProbeResponse: 3095 case C80211_SUBTYPE_MGMT_ProbeResponse:
3096 3096
diff --git a/drivers/net/wireless/hostap/Kconfig b/drivers/net/wireless/hostap/Kconfig
new file mode 100644
index 000000000000..56f41c714d38
--- /dev/null
+++ b/drivers/net/wireless/hostap/Kconfig
@@ -0,0 +1,73 @@
1config HOSTAP
2 tristate "IEEE 802.11 for Host AP (Prism2/2.5/3 and WEP/TKIP/CCMP)"
3 depends on NET_RADIO
4 select IEEE80211
5 select IEEE80211_CRYPT_WEP
6 ---help---
7 Shared driver code for IEEE 802.11b wireless cards based on
8 Intersil Prism2/2.5/3 chipset. This driver supports so called
9 Host AP mode that allows the card to act as an IEEE 802.11
10 access point.
11
12 See <http://hostap.epitest.fi/> for more information about the
13 Host AP driver configuration and tools. This site includes
14 information and tools (hostapd and wpa_supplicant) for WPA/WPA2
15 support.
16
17 This option includes the base Host AP driver code that is shared by
18 different hardware models. You will also need to enable support for
19 PLX/PCI/CS version of the driver to actually use the driver.
20
21 The driver can be compiled as a module and it will be called
22 "hostap.ko".
23
24config HOSTAP_FIRMWARE
25 bool "Support downloading firmware images with Host AP driver"
26 depends on HOSTAP
27 ---help---
28 Configure Host AP driver to include support for firmware image
29 download. Current version supports only downloading to volatile, i.e.,
30 RAM memory. Flash upgrade is not yet supported.
31
32 Firmware image downloading needs user space tool, prism2_srec. It is
33 available from http://hostap.epitest.fi/.
34
35config HOSTAP_PLX
36 tristate "Host AP driver for Prism2/2.5/3 in PLX9052 PCI adaptors"
37 depends on PCI && HOSTAP
38 ---help---
39 Host AP driver's version for Prism2/2.5/3 PC Cards in PLX9052 based
40 PCI adaptors.
41
42 "Host AP support for Prism2/2.5/3 IEEE 802.11b" is required for this
43 driver and its help text includes more information about the Host AP
44 driver.
45
46 The driver can be compiled as a module and will be named
47 "hostap_plx.ko".
48
49config HOSTAP_PCI
50 tristate "Host AP driver for Prism2.5 PCI adaptors"
51 depends on PCI && HOSTAP
52 ---help---
53 Host AP driver's version for Prism2.5 PCI adaptors.
54
55 "Host AP support for Prism2/2.5/3 IEEE 802.11b" is required for this
56 driver and its help text includes more information about the Host AP
57 driver.
58
59 The driver can be compiled as a module and will be named
60 "hostap_pci.ko".
61
62config HOSTAP_CS
63 tristate "Host AP driver for Prism2/2.5/3 PC Cards"
64 depends on PCMCIA!=n && HOSTAP
65 ---help---
66 Host AP driver's version for Prism2/2.5/3 PC Cards.
67
68 "Host AP support for Prism2/2.5/3 IEEE 802.11b" is required for this
69 driver and its help text includes more information about the Host AP
70 driver.
71
72 The driver can be compiled as a module and will be named
73 "hostap_cs.ko".
diff --git a/drivers/net/wireless/hostap/Makefile b/drivers/net/wireless/hostap/Makefile
new file mode 100644
index 000000000000..fc62235bfc24
--- /dev/null
+++ b/drivers/net/wireless/hostap/Makefile
@@ -0,0 +1,5 @@
1obj-$(CONFIG_HOSTAP) += hostap.o
2
3obj-$(CONFIG_HOSTAP_CS) += hostap_cs.o
4obj-$(CONFIG_HOSTAP_PLX) += hostap_plx.o
5obj-$(CONFIG_HOSTAP_PCI) += hostap_pci.o
diff --git a/drivers/net/wireless/hostap/hostap.c b/drivers/net/wireless/hostap/hostap.c
new file mode 100644
index 000000000000..e7f5821b4942
--- /dev/null
+++ b/drivers/net/wireless/hostap/hostap.c
@@ -0,0 +1,1198 @@
1/*
2 * Host AP (software wireless LAN access point) driver for
3 * Intersil Prism2/2.5/3 - hostap.o module, common routines
4 *
5 * Copyright (c) 2001-2002, SSH Communications Security Corp and Jouni Malinen
6 * <jkmaline@cc.hut.fi>
7 * Copyright (c) 2002-2005, Jouni Malinen <jkmaline@cc.hut.fi>
8 *
9 * This program is free software; you can redistribute it and/or modify
10 * it under the terms of the GNU General Public License version 2 as
11 * published by the Free Software Foundation. See README and COPYING for
12 * more details.
13 */
14
15#include <linux/config.h>
16#include <linux/version.h>
17#include <linux/module.h>
18#include <linux/init.h>
19#include <linux/slab.h>
20#include <linux/proc_fs.h>
21#include <linux/if_arp.h>
22#include <linux/delay.h>
23#include <linux/random.h>
24#include <linux/workqueue.h>
25#include <linux/kmod.h>
26#include <linux/rtnetlink.h>
27#include <linux/wireless.h>
28#include <net/iw_handler.h>
29#include <net/ieee80211.h>
30#include <net/ieee80211_crypt.h>
31#include <asm/uaccess.h>
32
33#include "hostap_wlan.h"
34#include "hostap_80211.h"
35#include "hostap_ap.h"
36#include "hostap.h"
37
38MODULE_AUTHOR("Jouni Malinen");
39MODULE_DESCRIPTION("Host AP common routines");
40MODULE_LICENSE("GPL");
41MODULE_VERSION(PRISM2_VERSION);
42
43#define TX_TIMEOUT (2 * HZ)
44
45#define PRISM2_MAX_FRAME_SIZE 2304
46#define PRISM2_MIN_MTU 256
47/* FIX: */
48#define PRISM2_MAX_MTU (PRISM2_MAX_FRAME_SIZE - (6 /* LLC */ + 8 /* WEP */))
49
50
51/* hostap.c */
52static int prism2_wds_add(local_info_t *local, u8 *remote_addr,
53 int rtnl_locked);
54static int prism2_wds_del(local_info_t *local, u8 *remote_addr,
55 int rtnl_locked, int do_not_remove);
56
57/* hostap_ap.c */
58static int prism2_ap_get_sta_qual(local_info_t *local, struct sockaddr addr[],
59 struct iw_quality qual[], int buf_size,
60 int aplist);
61static int prism2_ap_translate_scan(struct net_device *dev, char *buffer);
62static int prism2_hostapd(struct ap_data *ap,
63 struct prism2_hostapd_param *param);
64static void * ap_crypt_get_ptrs(struct ap_data *ap, u8 *addr, int permanent,
65 struct ieee80211_crypt_data ***crypt);
66static void ap_control_kickall(struct ap_data *ap);
67#ifndef PRISM2_NO_KERNEL_IEEE80211_MGMT
68static int ap_control_add_mac(struct mac_restrictions *mac_restrictions,
69 u8 *mac);
70static int ap_control_del_mac(struct mac_restrictions *mac_restrictions,
71 u8 *mac);
72static void ap_control_flush_macs(struct mac_restrictions *mac_restrictions);
73static int ap_control_kick_mac(struct ap_data *ap, struct net_device *dev,
74 u8 *mac);
75#endif /* !PRISM2_NO_KERNEL_IEEE80211_MGMT */
76
77
78static const long freq_list[] = { 2412, 2417, 2422, 2427, 2432, 2437, 2442,
79 2447, 2452, 2457, 2462, 2467, 2472, 2484 };
80#define FREQ_COUNT (sizeof(freq_list) / sizeof(freq_list[0]))
81
82
83/* See IEEE 802.1H for LLC/SNAP encapsulation/decapsulation */
84/* Ethernet-II snap header (RFC1042 for most EtherTypes) */
85static unsigned char rfc1042_header[] =
86{ 0xaa, 0xaa, 0x03, 0x00, 0x00, 0x00 };
87/* Bridge-Tunnel header (for EtherTypes ETH_P_AARP and ETH_P_IPX) */
88static unsigned char bridge_tunnel_header[] =
89{ 0xaa, 0xaa, 0x03, 0x00, 0x00, 0xf8 };
90/* No encapsulation header if EtherType < 0x600 (=length) */
91
92
93/* FIX: these could be compiled separately and linked together to hostap.o */
94#include "hostap_ap.c"
95#include "hostap_info.c"
96#include "hostap_ioctl.c"
97#include "hostap_proc.c"
98#include "hostap_80211_rx.c"
99#include "hostap_80211_tx.c"
100
101
102struct net_device * hostap_add_interface(struct local_info *local,
103 int type, int rtnl_locked,
104 const char *prefix,
105 const char *name)
106{
107 struct net_device *dev, *mdev;
108 struct hostap_interface *iface;
109 int ret;
110
111 dev = alloc_etherdev(sizeof(struct hostap_interface));
112 if (dev == NULL)
113 return NULL;
114
115 iface = netdev_priv(dev);
116 iface->dev = dev;
117 iface->local = local;
118 iface->type = type;
119 list_add(&iface->list, &local->hostap_interfaces);
120
121 mdev = local->dev;
122 memcpy(dev->dev_addr, mdev->dev_addr, ETH_ALEN);
123 dev->base_addr = mdev->base_addr;
124 dev->irq = mdev->irq;
125 dev->mem_start = mdev->mem_start;
126 dev->mem_end = mdev->mem_end;
127
128 hostap_setup_dev(dev, local, 0);
129 dev->destructor = free_netdev;
130
131 sprintf(dev->name, "%s%s", prefix, name);
132 if (!rtnl_locked)
133 rtnl_lock();
134
135 ret = 0;
136 if (strchr(dev->name, '%'))
137 ret = dev_alloc_name(dev, dev->name);
138
139 SET_NETDEV_DEV(dev, mdev->class_dev.dev);
140 if (ret >= 0)
141 ret = register_netdevice(dev);
142
143 if (!rtnl_locked)
144 rtnl_unlock();
145
146 if (ret < 0) {
147 printk(KERN_WARNING "%s: failed to add new netdevice!\n",
148 dev->name);
149 free_netdev(dev);
150 return NULL;
151 }
152
153 printk(KERN_DEBUG "%s: registered netdevice %s\n",
154 mdev->name, dev->name);
155
156 return dev;
157}
158
159
160void hostap_remove_interface(struct net_device *dev, int rtnl_locked,
161 int remove_from_list)
162{
163 struct hostap_interface *iface;
164
165 if (!dev)
166 return;
167
168 iface = netdev_priv(dev);
169
170 if (remove_from_list) {
171 list_del(&iface->list);
172 }
173
174 if (dev == iface->local->ddev)
175 iface->local->ddev = NULL;
176 else if (dev == iface->local->apdev)
177 iface->local->apdev = NULL;
178 else if (dev == iface->local->stadev)
179 iface->local->stadev = NULL;
180
181 if (rtnl_locked)
182 unregister_netdevice(dev);
183 else
184 unregister_netdev(dev);
185
186 /* dev->destructor = free_netdev() will free the device data, including
187 * private data, when removing the device */
188}
189
190
191static inline int prism2_wds_special_addr(u8 *addr)
192{
193 if (addr[0] || addr[1] || addr[2] || addr[3] || addr[4] || addr[5])
194 return 0;
195
196 return 1;
197}
198
199
200static int prism2_wds_add(local_info_t *local, u8 *remote_addr,
201 int rtnl_locked)
202{
203 struct net_device *dev;
204 struct list_head *ptr;
205 struct hostap_interface *iface, *empty, *match;
206
207 empty = match = NULL;
208 read_lock_bh(&local->iface_lock);
209 list_for_each(ptr, &local->hostap_interfaces) {
210 iface = list_entry(ptr, struct hostap_interface, list);
211 if (iface->type != HOSTAP_INTERFACE_WDS)
212 continue;
213
214 if (prism2_wds_special_addr(iface->u.wds.remote_addr))
215 empty = iface;
216 else if (memcmp(iface->u.wds.remote_addr, remote_addr,
217 ETH_ALEN) == 0) {
218 match = iface;
219 break;
220 }
221 }
222 if (!match && empty && !prism2_wds_special_addr(remote_addr)) {
223 /* take pre-allocated entry into use */
224 memcpy(empty->u.wds.remote_addr, remote_addr, ETH_ALEN);
225 read_unlock_bh(&local->iface_lock);
226 printk(KERN_DEBUG "%s: using pre-allocated WDS netdevice %s\n",
227 local->dev->name, empty->dev->name);
228 return 0;
229 }
230 read_unlock_bh(&local->iface_lock);
231
232 if (!prism2_wds_special_addr(remote_addr)) {
233 if (match)
234 return -EEXIST;
235 hostap_add_sta(local->ap, remote_addr);
236 }
237
238 if (local->wds_connections >= local->wds_max_connections)
239 return -ENOBUFS;
240
241 /* verify that there is room for wds# postfix in the interface name */
242 if (strlen(local->dev->name) > IFNAMSIZ - 5) {
243 printk(KERN_DEBUG "'%s' too long base device name\n",
244 local->dev->name);
245 return -EINVAL;
246 }
247
248 dev = hostap_add_interface(local, HOSTAP_INTERFACE_WDS, rtnl_locked,
249 local->ddev->name, "wds%d");
250 if (dev == NULL)
251 return -ENOMEM;
252
253 iface = netdev_priv(dev);
254 memcpy(iface->u.wds.remote_addr, remote_addr, ETH_ALEN);
255
256 local->wds_connections++;
257
258 return 0;
259}
260
261
262static int prism2_wds_del(local_info_t *local, u8 *remote_addr,
263 int rtnl_locked, int do_not_remove)
264{
265 unsigned long flags;
266 struct list_head *ptr;
267 struct hostap_interface *iface, *selected = NULL;
268
269 write_lock_irqsave(&local->iface_lock, flags);
270 list_for_each(ptr, &local->hostap_interfaces) {
271 iface = list_entry(ptr, struct hostap_interface, list);
272 if (iface->type != HOSTAP_INTERFACE_WDS)
273 continue;
274
275 if (memcmp(iface->u.wds.remote_addr, remote_addr,
276 ETH_ALEN) == 0) {
277 selected = iface;
278 break;
279 }
280 }
281 if (selected && !do_not_remove)
282 list_del(&selected->list);
283 write_unlock_irqrestore(&local->iface_lock, flags);
284
285 if (selected) {
286 if (do_not_remove)
287 memset(selected->u.wds.remote_addr, 0, ETH_ALEN);
288 else {
289 hostap_remove_interface(selected->dev, rtnl_locked, 0);
290 local->wds_connections--;
291 }
292 }
293
294 return selected ? 0 : -ENODEV;
295}
296
297
298u16 hostap_tx_callback_register(local_info_t *local,
299 void (*func)(struct sk_buff *, int ok, void *),
300 void *data)
301{
302 unsigned long flags;
303 struct hostap_tx_callback_info *entry;
304
305 entry = (struct hostap_tx_callback_info *) kmalloc(sizeof(*entry),
306 GFP_ATOMIC);
307 if (entry == NULL)
308 return 0;
309
310 entry->func = func;
311 entry->data = data;
312
313 spin_lock_irqsave(&local->lock, flags);
314 entry->idx = local->tx_callback ? local->tx_callback->idx + 1 : 1;
315 entry->next = local->tx_callback;
316 local->tx_callback = entry;
317 spin_unlock_irqrestore(&local->lock, flags);
318
319 return entry->idx;
320}
321
322
323int hostap_tx_callback_unregister(local_info_t *local, u16 idx)
324{
325 unsigned long flags;
326 struct hostap_tx_callback_info *cb, *prev = NULL;
327
328 spin_lock_irqsave(&local->lock, flags);
329 cb = local->tx_callback;
330 while (cb != NULL && cb->idx != idx) {
331 prev = cb;
332 cb = cb->next;
333 }
334 if (cb) {
335 if (prev == NULL)
336 local->tx_callback = cb->next;
337 else
338 prev->next = cb->next;
339 kfree(cb);
340 }
341 spin_unlock_irqrestore(&local->lock, flags);
342
343 return cb ? 0 : -1;
344}
345
346
347/* val is in host byte order */
348int hostap_set_word(struct net_device *dev, int rid, u16 val)
349{
350 struct hostap_interface *iface;
351 u16 tmp = cpu_to_le16(val);
352 iface = netdev_priv(dev);
353 return iface->local->func->set_rid(dev, rid, &tmp, 2);
354}
355
356
357int hostap_set_string(struct net_device *dev, int rid, const char *val)
358{
359 struct hostap_interface *iface;
360 char buf[MAX_SSID_LEN + 2];
361 int len;
362
363 iface = netdev_priv(dev);
364 len = strlen(val);
365 if (len > MAX_SSID_LEN)
366 return -1;
367 memset(buf, 0, sizeof(buf));
368 buf[0] = len; /* little endian 16 bit word */
369 memcpy(buf + 2, val, len);
370
371 return iface->local->func->set_rid(dev, rid, &buf, MAX_SSID_LEN + 2);
372}
373
374
375u16 hostap_get_porttype(local_info_t *local)
376{
377 if (local->iw_mode == IW_MODE_ADHOC && local->pseudo_adhoc)
378 return HFA384X_PORTTYPE_PSEUDO_IBSS;
379 if (local->iw_mode == IW_MODE_ADHOC)
380 return HFA384X_PORTTYPE_IBSS;
381 if (local->iw_mode == IW_MODE_INFRA)
382 return HFA384X_PORTTYPE_BSS;
383 if (local->iw_mode == IW_MODE_REPEAT)
384 return HFA384X_PORTTYPE_WDS;
385 if (local->iw_mode == IW_MODE_MONITOR)
386 return HFA384X_PORTTYPE_PSEUDO_IBSS;
387 return HFA384X_PORTTYPE_HOSTAP;
388}
389
390
391int hostap_set_encryption(local_info_t *local)
392{
393 u16 val, old_val;
394 int i, keylen, len, idx;
395 char keybuf[WEP_KEY_LEN + 1];
396 enum { NONE, WEP, OTHER } encrypt_type;
397
398 idx = local->tx_keyidx;
399 if (local->crypt[idx] == NULL || local->crypt[idx]->ops == NULL)
400 encrypt_type = NONE;
401 else if (strcmp(local->crypt[idx]->ops->name, "WEP") == 0)
402 encrypt_type = WEP;
403 else
404 encrypt_type = OTHER;
405
406 if (local->func->get_rid(local->dev, HFA384X_RID_CNFWEPFLAGS, &val, 2,
407 1) < 0) {
408 printk(KERN_DEBUG "Could not read current WEP flags.\n");
409 goto fail;
410 }
411 le16_to_cpus(&val);
412 old_val = val;
413
414 if (encrypt_type != NONE || local->privacy_invoked)
415 val |= HFA384X_WEPFLAGS_PRIVACYINVOKED;
416 else
417 val &= ~HFA384X_WEPFLAGS_PRIVACYINVOKED;
418
419 if (local->open_wep || encrypt_type == NONE ||
420 ((local->ieee_802_1x || local->wpa) && local->host_decrypt))
421 val &= ~HFA384X_WEPFLAGS_EXCLUDEUNENCRYPTED;
422 else
423 val |= HFA384X_WEPFLAGS_EXCLUDEUNENCRYPTED;
424
425 if ((encrypt_type != NONE || local->privacy_invoked) &&
426 (encrypt_type == OTHER || local->host_encrypt))
427 val |= HFA384X_WEPFLAGS_HOSTENCRYPT;
428 else
429 val &= ~HFA384X_WEPFLAGS_HOSTENCRYPT;
430 if ((encrypt_type != NONE || local->privacy_invoked) &&
431 (encrypt_type == OTHER || local->host_decrypt))
432 val |= HFA384X_WEPFLAGS_HOSTDECRYPT;
433 else
434 val &= ~HFA384X_WEPFLAGS_HOSTDECRYPT;
435
436 if (val != old_val &&
437 hostap_set_word(local->dev, HFA384X_RID_CNFWEPFLAGS, val)) {
438 printk(KERN_DEBUG "Could not write new WEP flags (0x%x)\n",
439 val);
440 goto fail;
441 }
442
443 if (encrypt_type != WEP)
444 return 0;
445
446 /* 104-bit support seems to require that all the keys are set to the
447 * same keylen */
448 keylen = 6; /* first 5 octets */
449 len = local->crypt[idx]->ops->get_key(keybuf, sizeof(keybuf),
450 NULL, local->crypt[idx]->priv);
451 if (idx >= 0 && idx < WEP_KEYS && len > 5)
452 keylen = WEP_KEY_LEN + 1; /* first 13 octets */
453
454 for (i = 0; i < WEP_KEYS; i++) {
455 memset(keybuf, 0, sizeof(keybuf));
456 if (local->crypt[i]) {
457 (void) local->crypt[i]->ops->get_key(
458 keybuf, sizeof(keybuf),
459 NULL, local->crypt[i]->priv);
460 }
461 if (local->func->set_rid(local->dev,
462 HFA384X_RID_CNFDEFAULTKEY0 + i,
463 keybuf, keylen)) {
464 printk(KERN_DEBUG "Could not set key %d (len=%d)\n",
465 i, keylen);
466 goto fail;
467 }
468 }
469 if (hostap_set_word(local->dev, HFA384X_RID_CNFWEPDEFAULTKEYID, idx)) {
470 printk(KERN_DEBUG "Could not set default keyid %d\n", idx);
471 goto fail;
472 }
473
474 return 0;
475
476 fail:
477 printk(KERN_DEBUG "%s: encryption setup failed\n", local->dev->name);
478 return -1;
479}
480
481
482int hostap_set_antsel(local_info_t *local)
483{
484 u16 val;
485 int ret = 0;
486
487 if (local->antsel_tx != HOSTAP_ANTSEL_DO_NOT_TOUCH &&
488 local->func->cmd(local->dev, HFA384X_CMDCODE_READMIF,
489 HFA386X_CR_TX_CONFIGURE,
490 NULL, &val) == 0) {
491 val &= ~(BIT(2) | BIT(1));
492 switch (local->antsel_tx) {
493 case HOSTAP_ANTSEL_DIVERSITY:
494 val |= BIT(1);
495 break;
496 case HOSTAP_ANTSEL_LOW:
497 break;
498 case HOSTAP_ANTSEL_HIGH:
499 val |= BIT(2);
500 break;
501 }
502
503 if (local->func->cmd(local->dev, HFA384X_CMDCODE_WRITEMIF,
504 HFA386X_CR_TX_CONFIGURE, &val, NULL)) {
505 printk(KERN_INFO "%s: setting TX AntSel failed\n",
506 local->dev->name);
507 ret = -1;
508 }
509 }
510
511 if (local->antsel_rx != HOSTAP_ANTSEL_DO_NOT_TOUCH &&
512 local->func->cmd(local->dev, HFA384X_CMDCODE_READMIF,
513 HFA386X_CR_RX_CONFIGURE,
514 NULL, &val) == 0) {
515 val &= ~(BIT(1) | BIT(0));
516 switch (local->antsel_rx) {
517 case HOSTAP_ANTSEL_DIVERSITY:
518 break;
519 case HOSTAP_ANTSEL_LOW:
520 val |= BIT(0);
521 break;
522 case HOSTAP_ANTSEL_HIGH:
523 val |= BIT(0) | BIT(1);
524 break;
525 }
526
527 if (local->func->cmd(local->dev, HFA384X_CMDCODE_WRITEMIF,
528 HFA386X_CR_RX_CONFIGURE, &val, NULL)) {
529 printk(KERN_INFO "%s: setting RX AntSel failed\n",
530 local->dev->name);
531 ret = -1;
532 }
533 }
534
535 return ret;
536}
537
538
539int hostap_set_roaming(local_info_t *local)
540{
541 u16 val;
542
543 switch (local->host_roaming) {
544 case 1:
545 val = HFA384X_ROAMING_HOST;
546 break;
547 case 2:
548 val = HFA384X_ROAMING_DISABLED;
549 break;
550 case 0:
551 default:
552 val = HFA384X_ROAMING_FIRMWARE;
553 break;
554 }
555
556 return hostap_set_word(local->dev, HFA384X_RID_CNFROAMINGMODE, val);
557}
558
559
560int hostap_set_auth_algs(local_info_t *local)
561{
562 int val = local->auth_algs;
563 /* At least STA f/w v0.6.2 seems to have issues with cnfAuthentication
564 * set to include both Open and Shared Key flags. It tries to use
565 * Shared Key authentication in that case even if WEP keys are not
566 * configured.. STA f/w v0.7.6 is able to handle such configuration,
567 * but it is unknown when this was fixed between 0.6.2 .. 0.7.6. */
568 if (local->sta_fw_ver < PRISM2_FW_VER(0,7,0) &&
569 val != PRISM2_AUTH_OPEN && val != PRISM2_AUTH_SHARED_KEY)
570 val = PRISM2_AUTH_OPEN;
571
572 if (hostap_set_word(local->dev, HFA384X_RID_CNFAUTHENTICATION, val)) {
573 printk(KERN_INFO "%s: cnfAuthentication setting to 0x%x "
574 "failed\n", local->dev->name, local->auth_algs);
575 return -EINVAL;
576 }
577
578 return 0;
579}
580
581
582void hostap_dump_rx_header(const char *name, const struct hfa384x_rx_frame *rx)
583{
584 u16 status, fc;
585
586 status = __le16_to_cpu(rx->status);
587
588 printk(KERN_DEBUG "%s: RX status=0x%04x (port=%d, type=%d, "
589 "fcserr=%d) silence=%d signal=%d rate=%d rxflow=%d; "
590 "jiffies=%ld\n",
591 name, status, (status >> 8) & 0x07, status >> 13, status & 1,
592 rx->silence, rx->signal, rx->rate, rx->rxflow, jiffies);
593
594 fc = __le16_to_cpu(rx->frame_control);
595 printk(KERN_DEBUG " FC=0x%04x (type=%d:%d) dur=0x%04x seq=0x%04x "
596 "data_len=%d%s%s\n",
597 fc, WLAN_FC_GET_TYPE(fc) >> 2, WLAN_FC_GET_STYPE(fc) >> 4,
598 __le16_to_cpu(rx->duration_id), __le16_to_cpu(rx->seq_ctrl),
599 __le16_to_cpu(rx->data_len),
600 fc & IEEE80211_FCTL_TODS ? " [ToDS]" : "",
601 fc & IEEE80211_FCTL_FROMDS ? " [FromDS]" : "");
602
603 printk(KERN_DEBUG " A1=" MACSTR " A2=" MACSTR " A3=" MACSTR " A4="
604 MACSTR "\n",
605 MAC2STR(rx->addr1), MAC2STR(rx->addr2), MAC2STR(rx->addr3),
606 MAC2STR(rx->addr4));
607
608 printk(KERN_DEBUG " dst=" MACSTR " src=" MACSTR " len=%d\n",
609 MAC2STR(rx->dst_addr), MAC2STR(rx->src_addr),
610 __be16_to_cpu(rx->len));
611}
612
613
614void hostap_dump_tx_header(const char *name, const struct hfa384x_tx_frame *tx)
615{
616 u16 fc;
617
618 printk(KERN_DEBUG "%s: TX status=0x%04x retry_count=%d tx_rate=%d "
619 "tx_control=0x%04x; jiffies=%ld\n",
620 name, __le16_to_cpu(tx->status), tx->retry_count, tx->tx_rate,
621 __le16_to_cpu(tx->tx_control), jiffies);
622
623 fc = __le16_to_cpu(tx->frame_control);
624 printk(KERN_DEBUG " FC=0x%04x (type=%d:%d) dur=0x%04x seq=0x%04x "
625 "data_len=%d%s%s\n",
626 fc, WLAN_FC_GET_TYPE(fc) >> 2, WLAN_FC_GET_STYPE(fc) >> 4,
627 __le16_to_cpu(tx->duration_id), __le16_to_cpu(tx->seq_ctrl),
628 __le16_to_cpu(tx->data_len),
629 fc & IEEE80211_FCTL_TODS ? " [ToDS]" : "",
630 fc & IEEE80211_FCTL_FROMDS ? " [FromDS]" : "");
631
632 printk(KERN_DEBUG " A1=" MACSTR " A2=" MACSTR " A3=" MACSTR " A4="
633 MACSTR "\n",
634 MAC2STR(tx->addr1), MAC2STR(tx->addr2), MAC2STR(tx->addr3),
635 MAC2STR(tx->addr4));
636
637 printk(KERN_DEBUG " dst=" MACSTR " src=" MACSTR " len=%d\n",
638 MAC2STR(tx->dst_addr), MAC2STR(tx->src_addr),
639 __be16_to_cpu(tx->len));
640}
641
642
643int hostap_80211_header_parse(struct sk_buff *skb, unsigned char *haddr)
644{
645 memcpy(haddr, skb->mac.raw + 10, ETH_ALEN); /* addr2 */
646 return ETH_ALEN;
647}
648
649
650int hostap_80211_prism_header_parse(struct sk_buff *skb, unsigned char *haddr)
651{
652 if (*(u32 *)skb->mac.raw == LWNG_CAP_DID_BASE) {
653 memcpy(haddr, skb->mac.raw +
654 sizeof(struct linux_wlan_ng_prism_hdr) + 10,
655 ETH_ALEN); /* addr2 */
656 } else { /* (*(u32 *)skb->mac.raw == htonl(LWNG_CAPHDR_VERSION)) */
657 memcpy(haddr, skb->mac.raw +
658 sizeof(struct linux_wlan_ng_cap_hdr) + 10,
659 ETH_ALEN); /* addr2 */
660 }
661 return ETH_ALEN;
662}
663
664
665int hostap_80211_get_hdrlen(u16 fc)
666{
667 int hdrlen = 24;
668
669 switch (WLAN_FC_GET_TYPE(fc)) {
670 case IEEE80211_FTYPE_DATA:
671 if ((fc & IEEE80211_FCTL_FROMDS) && (fc & IEEE80211_FCTL_TODS))
672 hdrlen = 30; /* Addr4 */
673 break;
674 case IEEE80211_FTYPE_CTL:
675 switch (WLAN_FC_GET_STYPE(fc)) {
676 case IEEE80211_STYPE_CTS:
677 case IEEE80211_STYPE_ACK:
678 hdrlen = 10;
679 break;
680 default:
681 hdrlen = 16;
682 break;
683 }
684 break;
685 }
686
687 return hdrlen;
688}
689
690
691struct net_device_stats *hostap_get_stats(struct net_device *dev)
692{
693 struct hostap_interface *iface;
694 iface = netdev_priv(dev);
695 return &iface->stats;
696}
697
698
699static int prism2_close(struct net_device *dev)
700{
701 struct hostap_interface *iface;
702 local_info_t *local;
703
704 PDEBUG(DEBUG_FLOW, "%s: prism2_close\n", dev->name);
705
706 iface = netdev_priv(dev);
707 local = iface->local;
708
709 if (dev == local->ddev) {
710 prism2_sta_deauth(local, WLAN_REASON_DEAUTH_LEAVING);
711 }
712#ifndef PRISM2_NO_KERNEL_IEEE80211_MGMT
713 if (!local->hostapd && dev == local->dev &&
714 (!local->func->card_present || local->func->card_present(local)) &&
715 local->hw_ready && local->ap && local->iw_mode == IW_MODE_MASTER)
716 hostap_deauth_all_stas(dev, local->ap, 1);
717#endif /* PRISM2_NO_KERNEL_IEEE80211_MGMT */
718
719 if (local->func->dev_close && local->func->dev_close(local))
720 return 0;
721
722 if (dev == local->dev) {
723 local->func->hw_shutdown(dev, HOSTAP_HW_ENABLE_CMDCOMPL);
724 }
725
726 if (netif_running(dev)) {
727 netif_stop_queue(dev);
728 netif_device_detach(dev);
729 }
730
731 flush_scheduled_work();
732
733 module_put(local->hw_module);
734
735 local->num_dev_open--;
736
737 if (dev != local->dev && local->dev->flags & IFF_UP &&
738 local->master_dev_auto_open && local->num_dev_open == 1) {
739 /* Close master radio interface automatically if it was also
740 * opened automatically and we are now closing the last
741 * remaining non-master device. */
742 dev_close(local->dev);
743 }
744
745 return 0;
746}
747
748
749static int prism2_open(struct net_device *dev)
750{
751 struct hostap_interface *iface;
752 local_info_t *local;
753
754 PDEBUG(DEBUG_FLOW, "%s: prism2_open\n", dev->name);
755
756 iface = netdev_priv(dev);
757 local = iface->local;
758
759 if (local->no_pri) {
760 printk(KERN_DEBUG "%s: could not set interface UP - no PRI "
761 "f/w\n", dev->name);
762 return 1;
763 }
764
765 if ((local->func->card_present && !local->func->card_present(local)) ||
766 local->hw_downloading)
767 return -ENODEV;
768
769 if (local->func->dev_open && local->func->dev_open(local))
770 return 1;
771
772 if (!try_module_get(local->hw_module))
773 return -ENODEV;
774 local->num_dev_open++;
775
776 if (!local->dev_enabled && local->func->hw_enable(dev, 1)) {
777 printk(KERN_WARNING "%s: could not enable MAC port\n",
778 dev->name);
779 prism2_close(dev);
780 return 1;
781 }
782 if (!local->dev_enabled)
783 prism2_callback(local, PRISM2_CALLBACK_ENABLE);
784 local->dev_enabled = 1;
785
786 if (dev != local->dev && !(local->dev->flags & IFF_UP)) {
787 /* Master radio interface is needed for all operation, so open
788 * it automatically when any virtual net_device is opened. */
789 local->master_dev_auto_open = 1;
790 dev_open(local->dev);
791 }
792
793 netif_device_attach(dev);
794 netif_start_queue(dev);
795
796 return 0;
797}
798
799
800static int prism2_set_mac_address(struct net_device *dev, void *p)
801{
802 struct hostap_interface *iface;
803 local_info_t *local;
804 struct list_head *ptr;
805 struct sockaddr *addr = p;
806
807 iface = netdev_priv(dev);
808 local = iface->local;
809
810 if (local->func->set_rid(dev, HFA384X_RID_CNFOWNMACADDR, addr->sa_data,
811 ETH_ALEN) < 0 || local->func->reset_port(dev))
812 return -EINVAL;
813
814 read_lock_bh(&local->iface_lock);
815 list_for_each(ptr, &local->hostap_interfaces) {
816 iface = list_entry(ptr, struct hostap_interface, list);
817 memcpy(iface->dev->dev_addr, addr->sa_data, ETH_ALEN);
818 }
819 memcpy(local->dev->dev_addr, addr->sa_data, ETH_ALEN);
820 read_unlock_bh(&local->iface_lock);
821
822 return 0;
823}
824
825
826/* TODO: to be further implemented as soon as Prism2 fully supports
827 * GroupAddresses and correct documentation is available */
828void hostap_set_multicast_list_queue(void *data)
829{
830 struct net_device *dev = (struct net_device *) data;
831 struct hostap_interface *iface;
832 local_info_t *local;
833
834 iface = netdev_priv(dev);
835 local = iface->local;
836 if (hostap_set_word(dev, HFA384X_RID_PROMISCUOUSMODE,
837 local->is_promisc)) {
838 printk(KERN_INFO "%s: %sabling promiscuous mode failed\n",
839 dev->name, local->is_promisc ? "en" : "dis");
840 }
841}
842
843
844static void hostap_set_multicast_list(struct net_device *dev)
845{
846#if 0
847 /* FIX: promiscuous mode seems to be causing a lot of problems with
848 * some station firmware versions (FCSErr frames, invalid MACPort, etc.
849 * corrupted incoming frames). This code is now commented out while the
850 * problems are investigated. */
851 struct hostap_interface *iface;
852 local_info_t *local;
853
854 iface = netdev_priv(dev);
855 local = iface->local;
856 if ((dev->flags & IFF_ALLMULTI) || (dev->flags & IFF_PROMISC)) {
857 local->is_promisc = 1;
858 } else {
859 local->is_promisc = 0;
860 }
861
862 schedule_work(&local->set_multicast_list_queue);
863#endif
864}
865
866
867static int prism2_change_mtu(struct net_device *dev, int new_mtu)
868{
869 if (new_mtu < PRISM2_MIN_MTU || new_mtu > PRISM2_MAX_MTU)
870 return -EINVAL;
871
872 dev->mtu = new_mtu;
873 return 0;
874}
875
876
877static void prism2_tx_timeout(struct net_device *dev)
878{
879 struct hostap_interface *iface;
880 local_info_t *local;
881 struct hfa384x_regs regs;
882
883 iface = netdev_priv(dev);
884 local = iface->local;
885
886 printk(KERN_WARNING "%s Tx timed out! Resetting card\n", dev->name);
887 netif_stop_queue(local->dev);
888
889 local->func->read_regs(dev, &regs);
890 printk(KERN_DEBUG "%s: CMD=%04x EVSTAT=%04x "
891 "OFFSET0=%04x OFFSET1=%04x SWSUPPORT0=%04x\n",
892 dev->name, regs.cmd, regs.evstat, regs.offset0, regs.offset1,
893 regs.swsupport0);
894
895 local->func->schedule_reset(local);
896}
897
898
899void hostap_setup_dev(struct net_device *dev, local_info_t *local,
900 int main_dev)
901{
902 struct hostap_interface *iface;
903
904 iface = netdev_priv(dev);
905 ether_setup(dev);
906
907 /* kernel callbacks */
908 dev->get_stats = hostap_get_stats;
909 if (iface) {
910 /* Currently, we point to the proper spy_data only on
911 * the main_dev. This could be fixed. Jean II */
912 iface->wireless_data.spy_data = &iface->spy_data;
913 dev->wireless_data = &iface->wireless_data;
914 }
915 dev->wireless_handlers =
916 (struct iw_handler_def *) &hostap_iw_handler_def;
917 dev->do_ioctl = hostap_ioctl;
918 dev->open = prism2_open;
919 dev->stop = prism2_close;
920 dev->hard_start_xmit = hostap_data_start_xmit;
921 dev->set_mac_address = prism2_set_mac_address;
922 dev->set_multicast_list = hostap_set_multicast_list;
923 dev->change_mtu = prism2_change_mtu;
924 dev->tx_timeout = prism2_tx_timeout;
925 dev->watchdog_timeo = TX_TIMEOUT;
926
927 dev->mtu = local->mtu;
928 if (!main_dev) {
929 /* use main radio device queue */
930 dev->tx_queue_len = 0;
931 }
932
933 SET_ETHTOOL_OPS(dev, &prism2_ethtool_ops);
934
935 netif_stop_queue(dev);
936}
937
938
939static int hostap_enable_hostapd(local_info_t *local, int rtnl_locked)
940{
941 struct net_device *dev = local->dev;
942
943 if (local->apdev)
944 return -EEXIST;
945
946 printk(KERN_DEBUG "%s: enabling hostapd mode\n", dev->name);
947
948 local->apdev = hostap_add_interface(local, HOSTAP_INTERFACE_AP,
949 rtnl_locked, local->ddev->name,
950 "ap");
951 if (local->apdev == NULL)
952 return -ENOMEM;
953
954 local->apdev->hard_start_xmit = hostap_mgmt_start_xmit;
955 local->apdev->type = ARPHRD_IEEE80211;
956 local->apdev->hard_header_parse = hostap_80211_header_parse;
957
958 return 0;
959}
960
961
962static int hostap_disable_hostapd(local_info_t *local, int rtnl_locked)
963{
964 struct net_device *dev = local->dev;
965
966 printk(KERN_DEBUG "%s: disabling hostapd mode\n", dev->name);
967
968 hostap_remove_interface(local->apdev, rtnl_locked, 1);
969 local->apdev = NULL;
970
971 return 0;
972}
973
974
975static int hostap_enable_hostapd_sta(local_info_t *local, int rtnl_locked)
976{
977 struct net_device *dev = local->dev;
978
979 if (local->stadev)
980 return -EEXIST;
981
982 printk(KERN_DEBUG "%s: enabling hostapd STA mode\n", dev->name);
983
984 local->stadev = hostap_add_interface(local, HOSTAP_INTERFACE_STA,
985 rtnl_locked, local->ddev->name,
986 "sta");
987 if (local->stadev == NULL)
988 return -ENOMEM;
989
990 return 0;
991}
992
993
994static int hostap_disable_hostapd_sta(local_info_t *local, int rtnl_locked)
995{
996 struct net_device *dev = local->dev;
997
998 printk(KERN_DEBUG "%s: disabling hostapd mode\n", dev->name);
999
1000 hostap_remove_interface(local->stadev, rtnl_locked, 1);
1001 local->stadev = NULL;
1002
1003 return 0;
1004}
1005
1006
1007int hostap_set_hostapd(local_info_t *local, int val, int rtnl_locked)
1008{
1009 int ret;
1010
1011 if (val < 0 || val > 1)
1012 return -EINVAL;
1013
1014 if (local->hostapd == val)
1015 return 0;
1016
1017 if (val) {
1018 ret = hostap_enable_hostapd(local, rtnl_locked);
1019 if (ret == 0)
1020 local->hostapd = 1;
1021 } else {
1022 local->hostapd = 0;
1023 ret = hostap_disable_hostapd(local, rtnl_locked);
1024 if (ret != 0)
1025 local->hostapd = 1;
1026 }
1027
1028 return ret;
1029}
1030
1031
1032int hostap_set_hostapd_sta(local_info_t *local, int val, int rtnl_locked)
1033{
1034 int ret;
1035
1036 if (val < 0 || val > 1)
1037 return -EINVAL;
1038
1039 if (local->hostapd_sta == val)
1040 return 0;
1041
1042 if (val) {
1043 ret = hostap_enable_hostapd_sta(local, rtnl_locked);
1044 if (ret == 0)
1045 local->hostapd_sta = 1;
1046 } else {
1047 local->hostapd_sta = 0;
1048 ret = hostap_disable_hostapd_sta(local, rtnl_locked);
1049 if (ret != 0)
1050 local->hostapd_sta = 1;
1051 }
1052
1053
1054 return ret;
1055}
1056
1057
1058int prism2_update_comms_qual(struct net_device *dev)
1059{
1060 struct hostap_interface *iface;
1061 local_info_t *local;
1062 int ret = 0;
1063 struct hfa384x_comms_quality sq;
1064
1065 iface = netdev_priv(dev);
1066 local = iface->local;
1067 if (!local->sta_fw_ver)
1068 ret = -1;
1069 else if (local->sta_fw_ver >= PRISM2_FW_VER(1,3,1)) {
1070 if (local->func->get_rid(local->dev,
1071 HFA384X_RID_DBMCOMMSQUALITY,
1072 &sq, sizeof(sq), 1) >= 0) {
1073 local->comms_qual = (s16) le16_to_cpu(sq.comm_qual);
1074 local->avg_signal = (s16) le16_to_cpu(sq.signal_level);
1075 local->avg_noise = (s16) le16_to_cpu(sq.noise_level);
1076 local->last_comms_qual_update = jiffies;
1077 } else
1078 ret = -1;
1079 } else {
1080 if (local->func->get_rid(local->dev, HFA384X_RID_COMMSQUALITY,
1081 &sq, sizeof(sq), 1) >= 0) {
1082 local->comms_qual = le16_to_cpu(sq.comm_qual);
1083 local->avg_signal = HFA384X_LEVEL_TO_dBm(
1084 le16_to_cpu(sq.signal_level));
1085 local->avg_noise = HFA384X_LEVEL_TO_dBm(
1086 le16_to_cpu(sq.noise_level));
1087 local->last_comms_qual_update = jiffies;
1088 } else
1089 ret = -1;
1090 }
1091
1092 return ret;
1093}
1094
1095
1096int prism2_sta_send_mgmt(local_info_t *local, u8 *dst, u16 stype,
1097 u8 *body, size_t bodylen)
1098{
1099 struct sk_buff *skb;
1100 struct hostap_ieee80211_mgmt *mgmt;
1101 struct hostap_skb_tx_data *meta;
1102 struct net_device *dev = local->dev;
1103
1104 skb = dev_alloc_skb(IEEE80211_MGMT_HDR_LEN + bodylen);
1105 if (skb == NULL)
1106 return -ENOMEM;
1107
1108 mgmt = (struct hostap_ieee80211_mgmt *)
1109 skb_put(skb, IEEE80211_MGMT_HDR_LEN);
1110 memset(mgmt, 0, IEEE80211_MGMT_HDR_LEN);
1111 mgmt->frame_control = cpu_to_le16(IEEE80211_FTYPE_MGMT | stype);
1112 memcpy(mgmt->da, dst, ETH_ALEN);
1113 memcpy(mgmt->sa, dev->dev_addr, ETH_ALEN);
1114 memcpy(mgmt->bssid, dst, ETH_ALEN);
1115 if (body)
1116 memcpy(skb_put(skb, bodylen), body, bodylen);
1117
1118 meta = (struct hostap_skb_tx_data *) skb->cb;
1119 memset(meta, 0, sizeof(*meta));
1120 meta->magic = HOSTAP_SKB_TX_DATA_MAGIC;
1121 meta->iface = netdev_priv(dev);
1122
1123 skb->dev = dev;
1124 skb->mac.raw = skb->nh.raw = skb->data;
1125 dev_queue_xmit(skb);
1126
1127 return 0;
1128}
1129
1130
1131int prism2_sta_deauth(local_info_t *local, u16 reason)
1132{
1133 union iwreq_data wrqu;
1134 int ret;
1135
1136 if (local->iw_mode != IW_MODE_INFRA ||
1137 memcmp(local->bssid, "\x00\x00\x00\x00\x00\x00", ETH_ALEN) == 0 ||
1138 memcmp(local->bssid, "\x44\x44\x44\x44\x44\x44", ETH_ALEN) == 0)
1139 return 0;
1140
1141 reason = cpu_to_le16(reason);
1142 ret = prism2_sta_send_mgmt(local, local->bssid, IEEE80211_STYPE_DEAUTH,
1143 (u8 *) &reason, 2);
1144 memset(wrqu.ap_addr.sa_data, 0, ETH_ALEN);
1145 wireless_send_event(local->dev, SIOCGIWAP, &wrqu, NULL);
1146 return ret;
1147}
1148
1149
1150struct proc_dir_entry *hostap_proc;
1151
1152static int __init hostap_init(void)
1153{
1154 if (proc_net != NULL) {
1155 hostap_proc = proc_mkdir("hostap", proc_net);
1156 if (!hostap_proc)
1157 printk(KERN_WARNING "Failed to mkdir "
1158 "/proc/net/hostap\n");
1159 } else
1160 hostap_proc = NULL;
1161
1162 return 0;
1163}
1164
1165
1166static void __exit hostap_exit(void)
1167{
1168 if (hostap_proc != NULL) {
1169 hostap_proc = NULL;
1170 remove_proc_entry("hostap", proc_net);
1171 }
1172}
1173
1174
1175EXPORT_SYMBOL(hostap_set_word);
1176EXPORT_SYMBOL(hostap_set_string);
1177EXPORT_SYMBOL(hostap_get_porttype);
1178EXPORT_SYMBOL(hostap_set_encryption);
1179EXPORT_SYMBOL(hostap_set_antsel);
1180EXPORT_SYMBOL(hostap_set_roaming);
1181EXPORT_SYMBOL(hostap_set_auth_algs);
1182EXPORT_SYMBOL(hostap_dump_rx_header);
1183EXPORT_SYMBOL(hostap_dump_tx_header);
1184EXPORT_SYMBOL(hostap_80211_header_parse);
1185EXPORT_SYMBOL(hostap_80211_prism_header_parse);
1186EXPORT_SYMBOL(hostap_80211_get_hdrlen);
1187EXPORT_SYMBOL(hostap_get_stats);
1188EXPORT_SYMBOL(hostap_setup_dev);
1189EXPORT_SYMBOL(hostap_proc);
1190EXPORT_SYMBOL(hostap_set_multicast_list_queue);
1191EXPORT_SYMBOL(hostap_set_hostapd);
1192EXPORT_SYMBOL(hostap_set_hostapd_sta);
1193EXPORT_SYMBOL(hostap_add_interface);
1194EXPORT_SYMBOL(hostap_remove_interface);
1195EXPORT_SYMBOL(prism2_update_comms_qual);
1196
1197module_init(hostap_init);
1198module_exit(hostap_exit);
diff --git a/drivers/net/wireless/hostap/hostap.h b/drivers/net/wireless/hostap/hostap.h
new file mode 100644
index 000000000000..5fac89b8ce3a
--- /dev/null
+++ b/drivers/net/wireless/hostap/hostap.h
@@ -0,0 +1,57 @@
1#ifndef HOSTAP_H
2#define HOSTAP_H
3
4/* hostap.c */
5
6extern struct proc_dir_entry *hostap_proc;
7
8u16 hostap_tx_callback_register(local_info_t *local,
9 void (*func)(struct sk_buff *, int ok, void *),
10 void *data);
11int hostap_tx_callback_unregister(local_info_t *local, u16 idx);
12int hostap_set_word(struct net_device *dev, int rid, u16 val);
13int hostap_set_string(struct net_device *dev, int rid, const char *val);
14u16 hostap_get_porttype(local_info_t *local);
15int hostap_set_encryption(local_info_t *local);
16int hostap_set_antsel(local_info_t *local);
17int hostap_set_roaming(local_info_t *local);
18int hostap_set_auth_algs(local_info_t *local);
19void hostap_dump_rx_header(const char *name,
20 const struct hfa384x_rx_frame *rx);
21void hostap_dump_tx_header(const char *name,
22 const struct hfa384x_tx_frame *tx);
23int hostap_80211_header_parse(struct sk_buff *skb, unsigned char *haddr);
24int hostap_80211_prism_header_parse(struct sk_buff *skb, unsigned char *haddr);
25int hostap_80211_get_hdrlen(u16 fc);
26struct net_device_stats *hostap_get_stats(struct net_device *dev);
27void hostap_setup_dev(struct net_device *dev, local_info_t *local,
28 int main_dev);
29void hostap_set_multicast_list_queue(void *data);
30int hostap_set_hostapd(local_info_t *local, int val, int rtnl_locked);
31int hostap_set_hostapd_sta(local_info_t *local, int val, int rtnl_locked);
32void hostap_cleanup(local_info_t *local);
33void hostap_cleanup_handler(void *data);
34struct net_device * hostap_add_interface(struct local_info *local,
35 int type, int rtnl_locked,
36 const char *prefix, const char *name);
37void hostap_remove_interface(struct net_device *dev, int rtnl_locked,
38 int remove_from_list);
39int prism2_update_comms_qual(struct net_device *dev);
40int prism2_sta_send_mgmt(local_info_t *local, u8 *dst, u16 stype,
41 u8 *body, size_t bodylen);
42int prism2_sta_deauth(local_info_t *local, u16 reason);
43
44
45/* hostap_proc.c */
46
47void hostap_init_proc(local_info_t *local);
48void hostap_remove_proc(local_info_t *local);
49
50
51/* hostap_info.c */
52
53void hostap_info_init(local_info_t *local);
54void hostap_info_process(local_info_t *local, struct sk_buff *skb);
55
56
57#endif /* HOSTAP_H */
diff --git a/drivers/net/wireless/hostap/hostap_80211.h b/drivers/net/wireless/hostap/hostap_80211.h
new file mode 100644
index 000000000000..bf506f50d722
--- /dev/null
+++ b/drivers/net/wireless/hostap/hostap_80211.h
@@ -0,0 +1,96 @@
1#ifndef HOSTAP_80211_H
2#define HOSTAP_80211_H
3
4struct hostap_ieee80211_mgmt {
5 u16 frame_control;
6 u16 duration;
7 u8 da[6];
8 u8 sa[6];
9 u8 bssid[6];
10 u16 seq_ctrl;
11 union {
12 struct {
13 u16 auth_alg;
14 u16 auth_transaction;
15 u16 status_code;
16 /* possibly followed by Challenge text */
17 u8 variable[0];
18 } __attribute__ ((packed)) auth;
19 struct {
20 u16 reason_code;
21 } __attribute__ ((packed)) deauth;
22 struct {
23 u16 capab_info;
24 u16 listen_interval;
25 /* followed by SSID and Supported rates */
26 u8 variable[0];
27 } __attribute__ ((packed)) assoc_req;
28 struct {
29 u16 capab_info;
30 u16 status_code;
31 u16 aid;
32 /* followed by Supported rates */
33 u8 variable[0];
34 } __attribute__ ((packed)) assoc_resp, reassoc_resp;
35 struct {
36 u16 capab_info;
37 u16 listen_interval;
38 u8 current_ap[6];
39 /* followed by SSID and Supported rates */
40 u8 variable[0];
41 } __attribute__ ((packed)) reassoc_req;
42 struct {
43 u16 reason_code;
44 } __attribute__ ((packed)) disassoc;
45 struct {
46 } __attribute__ ((packed)) probe_req;
47 struct {
48 u8 timestamp[8];
49 u16 beacon_int;
50 u16 capab_info;
51 /* followed by some of SSID, Supported rates,
52 * FH Params, DS Params, CF Params, IBSS Params, TIM */
53 u8 variable[0];
54 } __attribute__ ((packed)) beacon, probe_resp;
55 } u;
56} __attribute__ ((packed));
57
58
59#define IEEE80211_MGMT_HDR_LEN 24
60#define IEEE80211_DATA_HDR3_LEN 24
61#define IEEE80211_DATA_HDR4_LEN 30
62
63
64struct hostap_80211_rx_status {
65 u32 mac_time;
66 u8 signal;
67 u8 noise;
68 u16 rate; /* in 100 kbps */
69};
70
71
72void hostap_80211_rx(struct net_device *dev, struct sk_buff *skb,
73 struct hostap_80211_rx_status *rx_stats);
74
75
76/* prism2_rx_80211 'type' argument */
77enum {
78 PRISM2_RX_MONITOR, PRISM2_RX_MGMT, PRISM2_RX_NON_ASSOC,
79 PRISM2_RX_NULLFUNC_ACK
80};
81
82int prism2_rx_80211(struct net_device *dev, struct sk_buff *skb,
83 struct hostap_80211_rx_status *rx_stats, int type);
84void hostap_80211_rx(struct net_device *dev, struct sk_buff *skb,
85 struct hostap_80211_rx_status *rx_stats);
86void hostap_dump_rx_80211(const char *name, struct sk_buff *skb,
87 struct hostap_80211_rx_status *rx_stats);
88
89void hostap_dump_tx_80211(const char *name, struct sk_buff *skb);
90int hostap_data_start_xmit(struct sk_buff *skb, struct net_device *dev);
91int hostap_mgmt_start_xmit(struct sk_buff *skb, struct net_device *dev);
92struct sk_buff * hostap_tx_encrypt(struct sk_buff *skb,
93 struct ieee80211_crypt_data *crypt);
94int hostap_master_start_xmit(struct sk_buff *skb, struct net_device *dev);
95
96#endif /* HOSTAP_80211_H */
diff --git a/drivers/net/wireless/hostap/hostap_80211_rx.c b/drivers/net/wireless/hostap/hostap_80211_rx.c
new file mode 100644
index 000000000000..b0501243b175
--- /dev/null
+++ b/drivers/net/wireless/hostap/hostap_80211_rx.c
@@ -0,0 +1,1091 @@
1#include <linux/etherdevice.h>
2
3#include "hostap_80211.h"
4#include "hostap.h"
5
6void hostap_dump_rx_80211(const char *name, struct sk_buff *skb,
7 struct hostap_80211_rx_status *rx_stats)
8{
9 struct ieee80211_hdr *hdr;
10 u16 fc;
11
12 hdr = (struct ieee80211_hdr *) skb->data;
13
14 printk(KERN_DEBUG "%s: RX signal=%d noise=%d rate=%d len=%d "
15 "jiffies=%ld\n",
16 name, rx_stats->signal, rx_stats->noise, rx_stats->rate,
17 skb->len, jiffies);
18
19 if (skb->len < 2)
20 return;
21
22 fc = le16_to_cpu(hdr->frame_ctl);
23 printk(KERN_DEBUG " FC=0x%04x (type=%d:%d)%s%s",
24 fc, WLAN_FC_GET_TYPE(fc) >> 2, WLAN_FC_GET_STYPE(fc) >> 4,
25 fc & IEEE80211_FCTL_TODS ? " [ToDS]" : "",
26 fc & IEEE80211_FCTL_FROMDS ? " [FromDS]" : "");
27
28 if (skb->len < IEEE80211_DATA_HDR3_LEN) {
29 printk("\n");
30 return;
31 }
32
33 printk(" dur=0x%04x seq=0x%04x\n", le16_to_cpu(hdr->duration_id),
34 le16_to_cpu(hdr->seq_ctl));
35
36 printk(KERN_DEBUG " A1=" MACSTR " A2=" MACSTR " A3=" MACSTR,
37 MAC2STR(hdr->addr1), MAC2STR(hdr->addr2), MAC2STR(hdr->addr3));
38 if (skb->len >= 30)
39 printk(" A4=" MACSTR, MAC2STR(hdr->addr4));
40 printk("\n");
41}
42
43
44/* Send RX frame to netif with 802.11 (and possible prism) header.
45 * Called from hardware or software IRQ context. */
46int prism2_rx_80211(struct net_device *dev, struct sk_buff *skb,
47 struct hostap_80211_rx_status *rx_stats, int type)
48{
49 struct hostap_interface *iface;
50 local_info_t *local;
51 int hdrlen, phdrlen, head_need, tail_need;
52 u16 fc;
53 int prism_header, ret;
54 struct ieee80211_hdr *hdr;
55
56 iface = netdev_priv(dev);
57 local = iface->local;
58 dev->last_rx = jiffies;
59
60 if (dev->type == ARPHRD_IEEE80211_PRISM) {
61 if (local->monitor_type == PRISM2_MONITOR_PRISM) {
62 prism_header = 1;
63 phdrlen = sizeof(struct linux_wlan_ng_prism_hdr);
64 } else { /* local->monitor_type == PRISM2_MONITOR_CAPHDR */
65 prism_header = 2;
66 phdrlen = sizeof(struct linux_wlan_ng_cap_hdr);
67 }
68 } else {
69 prism_header = 0;
70 phdrlen = 0;
71 }
72
73 hdr = (struct ieee80211_hdr *) skb->data;
74 fc = le16_to_cpu(hdr->frame_ctl);
75
76 if (type == PRISM2_RX_MGMT && (fc & IEEE80211_FCTL_VERS)) {
77 printk(KERN_DEBUG "%s: dropped management frame with header "
78 "version %d\n", dev->name, fc & IEEE80211_FCTL_VERS);
79 dev_kfree_skb_any(skb);
80 return 0;
81 }
82
83 hdrlen = hostap_80211_get_hdrlen(fc);
84
85 /* check if there is enough room for extra data; if not, expand skb
86 * buffer to be large enough for the changes */
87 head_need = phdrlen;
88 tail_need = 0;
89#ifdef PRISM2_ADD_BOGUS_CRC
90 tail_need += 4;
91#endif /* PRISM2_ADD_BOGUS_CRC */
92
93 head_need -= skb_headroom(skb);
94 tail_need -= skb_tailroom(skb);
95
96 if (head_need > 0 || tail_need > 0) {
97 if (pskb_expand_head(skb, head_need > 0 ? head_need : 0,
98 tail_need > 0 ? tail_need : 0,
99 GFP_ATOMIC)) {
100 printk(KERN_DEBUG "%s: prism2_rx_80211 failed to "
101 "reallocate skb buffer\n", dev->name);
102 dev_kfree_skb_any(skb);
103 return 0;
104 }
105 }
106
107 /* We now have an skb with enough head and tail room, so just insert
108 * the extra data */
109
110#ifdef PRISM2_ADD_BOGUS_CRC
111 memset(skb_put(skb, 4), 0xff, 4); /* Prism2 strips CRC */
112#endif /* PRISM2_ADD_BOGUS_CRC */
113
114 if (prism_header == 1) {
115 struct linux_wlan_ng_prism_hdr *hdr;
116 hdr = (struct linux_wlan_ng_prism_hdr *)
117 skb_push(skb, phdrlen);
118 memset(hdr, 0, phdrlen);
119 hdr->msgcode = LWNG_CAP_DID_BASE;
120 hdr->msglen = sizeof(*hdr);
121 memcpy(hdr->devname, dev->name, sizeof(hdr->devname));
122#define LWNG_SETVAL(f,i,s,l,d) \
123hdr->f.did = LWNG_CAP_DID_BASE | (i << 12); \
124hdr->f.status = s; hdr->f.len = l; hdr->f.data = d
125 LWNG_SETVAL(hosttime, 1, 0, 4, jiffies);
126 LWNG_SETVAL(mactime, 2, 0, 4, rx_stats->mac_time);
127 LWNG_SETVAL(channel, 3, 1 /* no value */, 4, 0);
128 LWNG_SETVAL(rssi, 4, 1 /* no value */, 4, 0);
129 LWNG_SETVAL(sq, 5, 1 /* no value */, 4, 0);
130 LWNG_SETVAL(signal, 6, 0, 4, rx_stats->signal);
131 LWNG_SETVAL(noise, 7, 0, 4, rx_stats->noise);
132 LWNG_SETVAL(rate, 8, 0, 4, rx_stats->rate / 5);
133 LWNG_SETVAL(istx, 9, 0, 4, 0);
134 LWNG_SETVAL(frmlen, 10, 0, 4, skb->len - phdrlen);
135#undef LWNG_SETVAL
136 } else if (prism_header == 2) {
137 struct linux_wlan_ng_cap_hdr *hdr;
138 hdr = (struct linux_wlan_ng_cap_hdr *)
139 skb_push(skb, phdrlen);
140 memset(hdr, 0, phdrlen);
141 hdr->version = htonl(LWNG_CAPHDR_VERSION);
142 hdr->length = htonl(phdrlen);
143 hdr->mactime = __cpu_to_be64(rx_stats->mac_time);
144 hdr->hosttime = __cpu_to_be64(jiffies);
145 hdr->phytype = htonl(4); /* dss_dot11_b */
146 hdr->channel = htonl(local->channel);
147 hdr->datarate = htonl(rx_stats->rate);
148 hdr->antenna = htonl(0); /* unknown */
149 hdr->priority = htonl(0); /* unknown */
150 hdr->ssi_type = htonl(3); /* raw */
151 hdr->ssi_signal = htonl(rx_stats->signal);
152 hdr->ssi_noise = htonl(rx_stats->noise);
153 hdr->preamble = htonl(0); /* unknown */
154 hdr->encoding = htonl(1); /* cck */
155 }
156
157 ret = skb->len - phdrlen;
158 skb->dev = dev;
159 skb->mac.raw = skb->data;
160 skb_pull(skb, hdrlen);
161 if (prism_header)
162 skb_pull(skb, phdrlen);
163 skb->pkt_type = PACKET_OTHERHOST;
164 skb->protocol = __constant_htons(ETH_P_802_2);
165 memset(skb->cb, 0, sizeof(skb->cb));
166 netif_rx(skb);
167
168 return ret;
169}
170
171
172/* Called only as a tasklet (software IRQ) */
173static void monitor_rx(struct net_device *dev, struct sk_buff *skb,
174 struct hostap_80211_rx_status *rx_stats)
175{
176 struct net_device_stats *stats;
177 int len;
178
179 len = prism2_rx_80211(dev, skb, rx_stats, PRISM2_RX_MONITOR);
180 stats = hostap_get_stats(dev);
181 stats->rx_packets++;
182 stats->rx_bytes += len;
183}
184
185
186/* Called only as a tasklet (software IRQ) */
187static struct prism2_frag_entry *
188prism2_frag_cache_find(local_info_t *local, unsigned int seq,
189 unsigned int frag, u8 *src, u8 *dst)
190{
191 struct prism2_frag_entry *entry;
192 int i;
193
194 for (i = 0; i < PRISM2_FRAG_CACHE_LEN; i++) {
195 entry = &local->frag_cache[i];
196 if (entry->skb != NULL &&
197 time_after(jiffies, entry->first_frag_time + 2 * HZ)) {
198 printk(KERN_DEBUG "%s: expiring fragment cache entry "
199 "seq=%u last_frag=%u\n",
200 local->dev->name, entry->seq, entry->last_frag);
201 dev_kfree_skb(entry->skb);
202 entry->skb = NULL;
203 }
204
205 if (entry->skb != NULL && entry->seq == seq &&
206 (entry->last_frag + 1 == frag || frag == -1) &&
207 memcmp(entry->src_addr, src, ETH_ALEN) == 0 &&
208 memcmp(entry->dst_addr, dst, ETH_ALEN) == 0)
209 return entry;
210 }
211
212 return NULL;
213}
214
215
216/* Called only as a tasklet (software IRQ) */
217static struct sk_buff *
218prism2_frag_cache_get(local_info_t *local, struct ieee80211_hdr *hdr)
219{
220 struct sk_buff *skb = NULL;
221 u16 sc;
222 unsigned int frag, seq;
223 struct prism2_frag_entry *entry;
224
225 sc = le16_to_cpu(hdr->seq_ctl);
226 frag = WLAN_GET_SEQ_FRAG(sc);
227 seq = WLAN_GET_SEQ_SEQ(sc) >> 4;
228
229 if (frag == 0) {
230 /* Reserve enough space to fit maximum frame length */
231 skb = dev_alloc_skb(local->dev->mtu +
232 sizeof(struct ieee80211_hdr) +
233 8 /* LLC */ +
234 2 /* alignment */ +
235 8 /* WEP */ + ETH_ALEN /* WDS */);
236 if (skb == NULL)
237 return NULL;
238
239 entry = &local->frag_cache[local->frag_next_idx];
240 local->frag_next_idx++;
241 if (local->frag_next_idx >= PRISM2_FRAG_CACHE_LEN)
242 local->frag_next_idx = 0;
243
244 if (entry->skb != NULL)
245 dev_kfree_skb(entry->skb);
246
247 entry->first_frag_time = jiffies;
248 entry->seq = seq;
249 entry->last_frag = frag;
250 entry->skb = skb;
251 memcpy(entry->src_addr, hdr->addr2, ETH_ALEN);
252 memcpy(entry->dst_addr, hdr->addr1, ETH_ALEN);
253 } else {
254 /* received a fragment of a frame for which the head fragment
255 * should have already been received */
256 entry = prism2_frag_cache_find(local, seq, frag, hdr->addr2,
257 hdr->addr1);
258 if (entry != NULL) {
259 entry->last_frag = frag;
260 skb = entry->skb;
261 }
262 }
263
264 return skb;
265}
266
267
268/* Called only as a tasklet (software IRQ) */
269static int prism2_frag_cache_invalidate(local_info_t *local,
270 struct ieee80211_hdr *hdr)
271{
272 u16 sc;
273 unsigned int seq;
274 struct prism2_frag_entry *entry;
275
276 sc = le16_to_cpu(hdr->seq_ctl);
277 seq = WLAN_GET_SEQ_SEQ(sc) >> 4;
278
279 entry = prism2_frag_cache_find(local, seq, -1, hdr->addr2, hdr->addr1);
280
281 if (entry == NULL) {
282 printk(KERN_DEBUG "%s: could not invalidate fragment cache "
283 "entry (seq=%u)\n",
284 local->dev->name, seq);
285 return -1;
286 }
287
288 entry->skb = NULL;
289 return 0;
290}
291
292
293static struct hostap_bss_info *__hostap_get_bss(local_info_t *local, u8 *bssid,
294 u8 *ssid, size_t ssid_len)
295{
296 struct list_head *ptr;
297 struct hostap_bss_info *bss;
298
299 list_for_each(ptr, &local->bss_list) {
300 bss = list_entry(ptr, struct hostap_bss_info, list);
301 if (memcmp(bss->bssid, bssid, ETH_ALEN) == 0 &&
302 (ssid == NULL ||
303 (ssid_len == bss->ssid_len &&
304 memcmp(ssid, bss->ssid, ssid_len) == 0))) {
305 list_move(&bss->list, &local->bss_list);
306 return bss;
307 }
308 }
309
310 return NULL;
311}
312
313
314static struct hostap_bss_info *__hostap_add_bss(local_info_t *local, u8 *bssid,
315 u8 *ssid, size_t ssid_len)
316{
317 struct hostap_bss_info *bss;
318
319 if (local->num_bss_info >= HOSTAP_MAX_BSS_COUNT) {
320 bss = list_entry(local->bss_list.prev,
321 struct hostap_bss_info, list);
322 list_del(&bss->list);
323 local->num_bss_info--;
324 } else {
325 bss = (struct hostap_bss_info *)
326 kmalloc(sizeof(*bss), GFP_ATOMIC);
327 if (bss == NULL)
328 return NULL;
329 }
330
331 memset(bss, 0, sizeof(*bss));
332 memcpy(bss->bssid, bssid, ETH_ALEN);
333 memcpy(bss->ssid, ssid, ssid_len);
334 bss->ssid_len = ssid_len;
335 local->num_bss_info++;
336 list_add(&bss->list, &local->bss_list);
337 return bss;
338}
339
340
341static void __hostap_expire_bss(local_info_t *local)
342{
343 struct hostap_bss_info *bss;
344
345 while (local->num_bss_info > 0) {
346 bss = list_entry(local->bss_list.prev,
347 struct hostap_bss_info, list);
348 if (!time_after(jiffies, bss->last_update + 60 * HZ))
349 break;
350
351 list_del(&bss->list);
352 local->num_bss_info--;
353 kfree(bss);
354 }
355}
356
357
358/* Both IEEE 802.11 Beacon and Probe Response frames have similar structure, so
359 * the same routine can be used to parse both of them. */
360static void hostap_rx_sta_beacon(local_info_t *local, struct sk_buff *skb,
361 int stype)
362{
363 struct hostap_ieee80211_mgmt *mgmt;
364 int left, chan = 0;
365 u8 *pos;
366 u8 *ssid = NULL, *wpa = NULL, *rsn = NULL;
367 size_t ssid_len = 0, wpa_len = 0, rsn_len = 0;
368 struct hostap_bss_info *bss;
369
370 if (skb->len < IEEE80211_MGMT_HDR_LEN + sizeof(mgmt->u.beacon))
371 return;
372
373 mgmt = (struct hostap_ieee80211_mgmt *) skb->data;
374 pos = mgmt->u.beacon.variable;
375 left = skb->len - (pos - skb->data);
376
377 while (left >= 2) {
378 if (2 + pos[1] > left)
379 return; /* parse failed */
380 switch (*pos) {
381 case WLAN_EID_SSID:
382 ssid = pos + 2;
383 ssid_len = pos[1];
384 break;
385 case WLAN_EID_GENERIC:
386 if (pos[1] >= 4 &&
387 pos[2] == 0x00 && pos[3] == 0x50 &&
388 pos[4] == 0xf2 && pos[5] == 1) {
389 wpa = pos;
390 wpa_len = pos[1] + 2;
391 }
392 break;
393 case WLAN_EID_RSN:
394 rsn = pos;
395 rsn_len = pos[1] + 2;
396 break;
397 case WLAN_EID_DS_PARAMS:
398 if (pos[1] >= 1)
399 chan = pos[2];
400 break;
401 }
402 left -= 2 + pos[1];
403 pos += 2 + pos[1];
404 }
405
406 if (wpa_len > MAX_WPA_IE_LEN)
407 wpa_len = MAX_WPA_IE_LEN;
408 if (rsn_len > MAX_WPA_IE_LEN)
409 rsn_len = MAX_WPA_IE_LEN;
410 if (ssid_len > sizeof(bss->ssid))
411 ssid_len = sizeof(bss->ssid);
412
413 spin_lock(&local->lock);
414 bss = __hostap_get_bss(local, mgmt->bssid, ssid, ssid_len);
415 if (bss == NULL)
416 bss = __hostap_add_bss(local, mgmt->bssid, ssid, ssid_len);
417 if (bss) {
418 bss->last_update = jiffies;
419 bss->count++;
420 bss->capab_info = le16_to_cpu(mgmt->u.beacon.capab_info);
421 if (wpa) {
422 memcpy(bss->wpa_ie, wpa, wpa_len);
423 bss->wpa_ie_len = wpa_len;
424 } else
425 bss->wpa_ie_len = 0;
426 if (rsn) {
427 memcpy(bss->rsn_ie, rsn, rsn_len);
428 bss->rsn_ie_len = rsn_len;
429 } else
430 bss->rsn_ie_len = 0;
431 bss->chan = chan;
432 }
433 __hostap_expire_bss(local);
434 spin_unlock(&local->lock);
435}
436
437
438static inline int
439hostap_rx_frame_mgmt(local_info_t *local, struct sk_buff *skb,
440 struct hostap_80211_rx_status *rx_stats, u16 type,
441 u16 stype)
442{
443 if (local->iw_mode == IW_MODE_MASTER) {
444 hostap_update_sta_ps(local, (struct ieee80211_hdr *)
445 skb->data);
446 }
447
448 if (local->hostapd && type == IEEE80211_FTYPE_MGMT) {
449 if (stype == IEEE80211_STYPE_BEACON &&
450 local->iw_mode == IW_MODE_MASTER) {
451 struct sk_buff *skb2;
452 /* Process beacon frames also in kernel driver to
453 * update STA(AP) table statistics */
454 skb2 = skb_clone(skb, GFP_ATOMIC);
455 if (skb2)
456 hostap_rx(skb2->dev, skb2, rx_stats);
457 }
458
459 /* send management frames to the user space daemon for
460 * processing */
461 local->apdevstats.rx_packets++;
462 local->apdevstats.rx_bytes += skb->len;
463 if (local->apdev == NULL)
464 return -1;
465 prism2_rx_80211(local->apdev, skb, rx_stats, PRISM2_RX_MGMT);
466 return 0;
467 }
468
469 if (local->iw_mode == IW_MODE_MASTER) {
470 if (type != IEEE80211_FTYPE_MGMT &&
471 type != IEEE80211_FTYPE_CTL) {
472 printk(KERN_DEBUG "%s: unknown management frame "
473 "(type=0x%02x, stype=0x%02x) dropped\n",
474 skb->dev->name, type >> 2, stype >> 4);
475 return -1;
476 }
477
478 hostap_rx(skb->dev, skb, rx_stats);
479 return 0;
480 } else if (type == IEEE80211_FTYPE_MGMT &&
481 (stype == IEEE80211_STYPE_BEACON ||
482 stype == IEEE80211_STYPE_PROBE_RESP)) {
483 hostap_rx_sta_beacon(local, skb, stype);
484 return -1;
485 } else if (type == IEEE80211_FTYPE_MGMT &&
486 (stype == IEEE80211_STYPE_ASSOC_RESP ||
487 stype == IEEE80211_STYPE_REASSOC_RESP)) {
488 /* Ignore (Re)AssocResp silently since these are not currently
489 * needed but are still received when WPA/RSN mode is enabled.
490 */
491 return -1;
492 } else {
493 printk(KERN_DEBUG "%s: hostap_rx_frame_mgmt: dropped unhandled"
494 " management frame in non-Host AP mode (type=%d:%d)\n",
495 skb->dev->name, type >> 2, stype >> 4);
496 return -1;
497 }
498}
499
500
501/* Called only as a tasklet (software IRQ) */
502static inline struct net_device *prism2_rx_get_wds(local_info_t *local,
503 u8 *addr)
504{
505 struct hostap_interface *iface = NULL;
506 struct list_head *ptr;
507
508 read_lock_bh(&local->iface_lock);
509 list_for_each(ptr, &local->hostap_interfaces) {
510 iface = list_entry(ptr, struct hostap_interface, list);
511 if (iface->type == HOSTAP_INTERFACE_WDS &&
512 memcmp(iface->u.wds.remote_addr, addr, ETH_ALEN) == 0)
513 break;
514 iface = NULL;
515 }
516 read_unlock_bh(&local->iface_lock);
517
518 return iface ? iface->dev : NULL;
519}
520
521
522static inline int
523hostap_rx_frame_wds(local_info_t *local, struct ieee80211_hdr *hdr,
524 u16 fc, struct net_device **wds)
525{
526 /* FIX: is this really supposed to accept WDS frames only in Master
527 * mode? What about Repeater or Managed with WDS frames? */
528 if ((fc & (IEEE80211_FCTL_TODS | IEEE80211_FCTL_FROMDS)) !=
529 (IEEE80211_FCTL_TODS | IEEE80211_FCTL_FROMDS) &&
530 (local->iw_mode != IW_MODE_MASTER || !(fc & IEEE80211_FCTL_TODS)))
531 return 0; /* not a WDS frame */
532
533 /* Possible WDS frame: either IEEE 802.11 compliant (if FromDS)
534 * or own non-standard frame with 4th address after payload */
535 if (memcmp(hdr->addr1, local->dev->dev_addr, ETH_ALEN) != 0 &&
536 (hdr->addr1[0] != 0xff || hdr->addr1[1] != 0xff ||
537 hdr->addr1[2] != 0xff || hdr->addr1[3] != 0xff ||
538 hdr->addr1[4] != 0xff || hdr->addr1[5] != 0xff)) {
539 /* RA (or BSSID) is not ours - drop */
540 PDEBUG(DEBUG_EXTRA, "%s: received WDS frame with "
541 "not own or broadcast %s=" MACSTR "\n",
542 local->dev->name,
543 fc & IEEE80211_FCTL_FROMDS ? "RA" : "BSSID",
544 MAC2STR(hdr->addr1));
545 return -1;
546 }
547
548 /* check if the frame came from a registered WDS connection */
549 *wds = prism2_rx_get_wds(local, hdr->addr2);
550 if (*wds == NULL && fc & IEEE80211_FCTL_FROMDS &&
551 (local->iw_mode != IW_MODE_INFRA ||
552 !(local->wds_type & HOSTAP_WDS_AP_CLIENT) ||
553 memcmp(hdr->addr2, local->bssid, ETH_ALEN) != 0)) {
554 /* require that WDS link has been registered with TA or the
555 * frame is from current AP when using 'AP client mode' */
556 PDEBUG(DEBUG_EXTRA, "%s: received WDS[4 addr] frame "
557 "from unknown TA=" MACSTR "\n",
558 local->dev->name, MAC2STR(hdr->addr2));
559 if (local->ap && local->ap->autom_ap_wds)
560 hostap_wds_link_oper(local, hdr->addr2, WDS_ADD);
561 return -1;
562 }
563
564 if (*wds && !(fc & IEEE80211_FCTL_FROMDS) && local->ap &&
565 hostap_is_sta_assoc(local->ap, hdr->addr2)) {
566 /* STA is actually associated with us even though it has a
567 * registered WDS link. Assume it is in 'AP client' mode.
568 * Since this is a 3-addr frame, assume it is not (bogus) WDS
569 * frame and process it like any normal ToDS frame from
570 * associated STA. */
571 *wds = NULL;
572 }
573
574 return 0;
575}
576
577
578static int hostap_is_eapol_frame(local_info_t *local, struct sk_buff *skb)
579{
580 struct net_device *dev = local->dev;
581 u16 fc, ethertype;
582 struct ieee80211_hdr *hdr;
583 u8 *pos;
584
585 if (skb->len < 24)
586 return 0;
587
588 hdr = (struct ieee80211_hdr *) skb->data;
589 fc = le16_to_cpu(hdr->frame_ctl);
590
591 /* check that the frame is unicast frame to us */
592 if ((fc & (IEEE80211_FCTL_TODS | IEEE80211_FCTL_FROMDS)) ==
593 IEEE80211_FCTL_TODS &&
594 memcmp(hdr->addr1, dev->dev_addr, ETH_ALEN) == 0 &&
595 memcmp(hdr->addr3, dev->dev_addr, ETH_ALEN) == 0) {
596 /* ToDS frame with own addr BSSID and DA */
597 } else if ((fc & (IEEE80211_FCTL_TODS | IEEE80211_FCTL_FROMDS)) ==
598 IEEE80211_FCTL_FROMDS &&
599 memcmp(hdr->addr1, dev->dev_addr, ETH_ALEN) == 0) {
600 /* FromDS frame with own addr as DA */
601 } else
602 return 0;
603
604 if (skb->len < 24 + 8)
605 return 0;
606
607 /* check for port access entity Ethernet type */
608 pos = skb->data + 24;
609 ethertype = (pos[6] << 8) | pos[7];
610 if (ethertype == ETH_P_PAE)
611 return 1;
612
613 return 0;
614}
615
616
617/* Called only as a tasklet (software IRQ) */
618static inline int
619hostap_rx_frame_decrypt(local_info_t *local, struct sk_buff *skb,
620 struct ieee80211_crypt_data *crypt)
621{
622 struct ieee80211_hdr *hdr;
623 int res, hdrlen;
624
625 if (crypt == NULL || crypt->ops->decrypt_mpdu == NULL)
626 return 0;
627
628 hdr = (struct ieee80211_hdr *) skb->data;
629 hdrlen = hostap_80211_get_hdrlen(le16_to_cpu(hdr->frame_ctl));
630
631 if (local->tkip_countermeasures &&
632 strcmp(crypt->ops->name, "TKIP") == 0) {
633 if (net_ratelimit()) {
634 printk(KERN_DEBUG "%s: TKIP countermeasures: dropped "
635 "received packet from " MACSTR "\n",
636 local->dev->name, MAC2STR(hdr->addr2));
637 }
638 return -1;
639 }
640
641 atomic_inc(&crypt->refcnt);
642 res = crypt->ops->decrypt_mpdu(skb, hdrlen, crypt->priv);
643 atomic_dec(&crypt->refcnt);
644 if (res < 0) {
645 printk(KERN_DEBUG "%s: decryption failed (SA=" MACSTR
646 ") res=%d\n",
647 local->dev->name, MAC2STR(hdr->addr2), res);
648 local->comm_tallies.rx_discards_wep_undecryptable++;
649 return -1;
650 }
651
652 return res;
653}
654
655
656/* Called only as a tasklet (software IRQ) */
657static inline int
658hostap_rx_frame_decrypt_msdu(local_info_t *local, struct sk_buff *skb,
659 int keyidx, struct ieee80211_crypt_data *crypt)
660{
661 struct ieee80211_hdr *hdr;
662 int res, hdrlen;
663
664 if (crypt == NULL || crypt->ops->decrypt_msdu == NULL)
665 return 0;
666
667 hdr = (struct ieee80211_hdr *) skb->data;
668 hdrlen = hostap_80211_get_hdrlen(le16_to_cpu(hdr->frame_ctl));
669
670 atomic_inc(&crypt->refcnt);
671 res = crypt->ops->decrypt_msdu(skb, keyidx, hdrlen, crypt->priv);
672 atomic_dec(&crypt->refcnt);
673 if (res < 0) {
674 printk(KERN_DEBUG "%s: MSDU decryption/MIC verification failed"
675 " (SA=" MACSTR " keyidx=%d)\n",
676 local->dev->name, MAC2STR(hdr->addr2), keyidx);
677 return -1;
678 }
679
680 return 0;
681}
682
683
684/* All received frames are sent to this function. @skb contains the frame in
685 * IEEE 802.11 format, i.e., in the format it was sent over air.
686 * This function is called only as a tasklet (software IRQ). */
687void hostap_80211_rx(struct net_device *dev, struct sk_buff *skb,
688 struct hostap_80211_rx_status *rx_stats)
689{
690 struct hostap_interface *iface;
691 local_info_t *local;
692 struct ieee80211_hdr *hdr;
693 size_t hdrlen;
694 u16 fc, type, stype, sc;
695 struct net_device *wds = NULL;
696 struct net_device_stats *stats;
697 unsigned int frag;
698 u8 *payload;
699 struct sk_buff *skb2 = NULL;
700 u16 ethertype;
701 int frame_authorized = 0;
702 int from_assoc_ap = 0;
703 u8 dst[ETH_ALEN];
704 u8 src[ETH_ALEN];
705 struct ieee80211_crypt_data *crypt = NULL;
706 void *sta = NULL;
707 int keyidx = 0;
708
709 iface = netdev_priv(dev);
710 local = iface->local;
711 iface->stats.rx_packets++;
712 iface->stats.rx_bytes += skb->len;
713
714 /* dev is the master radio device; change this to be the default
715 * virtual interface (this may be changed to WDS device below) */
716 dev = local->ddev;
717 iface = netdev_priv(dev);
718
719 hdr = (struct ieee80211_hdr *) skb->data;
720 stats = hostap_get_stats(dev);
721
722 if (skb->len < 10)
723 goto rx_dropped;
724
725 fc = le16_to_cpu(hdr->frame_ctl);
726 type = WLAN_FC_GET_TYPE(fc);
727 stype = WLAN_FC_GET_STYPE(fc);
728 sc = le16_to_cpu(hdr->seq_ctl);
729 frag = WLAN_GET_SEQ_FRAG(sc);
730 hdrlen = hostap_80211_get_hdrlen(fc);
731
732 /* Put this code here so that we avoid duplicating it in all
733 * Rx paths. - Jean II */
734#ifdef IW_WIRELESS_SPY /* defined in iw_handler.h */
735 /* If spy monitoring on */
736 if (iface->spy_data.spy_number > 0) {
737 struct iw_quality wstats;
738 wstats.level = rx_stats->signal;
739 wstats.noise = rx_stats->noise;
740 wstats.updated = 6; /* No qual value */
741 /* Update spy records */
742 wireless_spy_update(dev, hdr->addr2, &wstats);
743 }
744#endif /* IW_WIRELESS_SPY */
745 hostap_update_rx_stats(local->ap, hdr, rx_stats);
746
747 if (local->iw_mode == IW_MODE_MONITOR) {
748 monitor_rx(dev, skb, rx_stats);
749 return;
750 }
751
752 if (local->host_decrypt) {
753 int idx = 0;
754 if (skb->len >= hdrlen + 3)
755 idx = skb->data[hdrlen + 3] >> 6;
756 crypt = local->crypt[idx];
757 sta = NULL;
758
759 /* Use station specific key to override default keys if the
760 * receiver address is a unicast address ("individual RA"). If
761 * bcrx_sta_key parameter is set, station specific key is used
762 * even with broad/multicast targets (this is against IEEE
763 * 802.11, but makes it easier to use different keys with
764 * stations that do not support WEP key mapping). */
765
766 if (!(hdr->addr1[0] & 0x01) || local->bcrx_sta_key)
767 (void) hostap_handle_sta_crypto(local, hdr, &crypt,
768 &sta);
769
770 /* allow NULL decrypt to indicate an station specific override
771 * for default encryption */
772 if (crypt && (crypt->ops == NULL ||
773 crypt->ops->decrypt_mpdu == NULL))
774 crypt = NULL;
775
776 if (!crypt && (fc & IEEE80211_FCTL_PROTECTED)) {
777#if 0
778 /* This seems to be triggered by some (multicast?)
779 * frames from other than current BSS, so just drop the
780 * frames silently instead of filling system log with
781 * these reports. */
782 printk(KERN_DEBUG "%s: WEP decryption failed (not set)"
783 " (SA=" MACSTR ")\n",
784 local->dev->name, MAC2STR(hdr->addr2));
785#endif
786 local->comm_tallies.rx_discards_wep_undecryptable++;
787 goto rx_dropped;
788 }
789 }
790
791 if (type != IEEE80211_FTYPE_DATA) {
792 if (type == IEEE80211_FTYPE_MGMT &&
793 stype == IEEE80211_STYPE_AUTH &&
794 fc & IEEE80211_FCTL_PROTECTED && local->host_decrypt &&
795 (keyidx = hostap_rx_frame_decrypt(local, skb, crypt)) < 0)
796 {
797 printk(KERN_DEBUG "%s: failed to decrypt mgmt::auth "
798 "from " MACSTR "\n", dev->name,
799 MAC2STR(hdr->addr2));
800 /* TODO: could inform hostapd about this so that it
801 * could send auth failure report */
802 goto rx_dropped;
803 }
804
805 if (hostap_rx_frame_mgmt(local, skb, rx_stats, type, stype))
806 goto rx_dropped;
807 else
808 goto rx_exit;
809 }
810
811 /* Data frame - extract src/dst addresses */
812 if (skb->len < IEEE80211_DATA_HDR3_LEN)
813 goto rx_dropped;
814
815 switch (fc & (IEEE80211_FCTL_FROMDS | IEEE80211_FCTL_TODS)) {
816 case IEEE80211_FCTL_FROMDS:
817 memcpy(dst, hdr->addr1, ETH_ALEN);
818 memcpy(src, hdr->addr3, ETH_ALEN);
819 break;
820 case IEEE80211_FCTL_TODS:
821 memcpy(dst, hdr->addr3, ETH_ALEN);
822 memcpy(src, hdr->addr2, ETH_ALEN);
823 break;
824 case IEEE80211_FCTL_FROMDS | IEEE80211_FCTL_TODS:
825 if (skb->len < IEEE80211_DATA_HDR4_LEN)
826 goto rx_dropped;
827 memcpy(dst, hdr->addr3, ETH_ALEN);
828 memcpy(src, hdr->addr4, ETH_ALEN);
829 break;
830 case 0:
831 memcpy(dst, hdr->addr1, ETH_ALEN);
832 memcpy(src, hdr->addr2, ETH_ALEN);
833 break;
834 }
835
836 if (hostap_rx_frame_wds(local, hdr, fc, &wds))
837 goto rx_dropped;
838 if (wds) {
839 skb->dev = dev = wds;
840 stats = hostap_get_stats(dev);
841 }
842
843 if (local->iw_mode == IW_MODE_MASTER && !wds &&
844 (fc & (IEEE80211_FCTL_TODS | IEEE80211_FCTL_FROMDS)) ==
845 IEEE80211_FCTL_FROMDS &&
846 local->stadev &&
847 memcmp(hdr->addr2, local->assoc_ap_addr, ETH_ALEN) == 0) {
848 /* Frame from BSSID of the AP for which we are a client */
849 skb->dev = dev = local->stadev;
850 stats = hostap_get_stats(dev);
851 from_assoc_ap = 1;
852 }
853
854 dev->last_rx = jiffies;
855
856 if ((local->iw_mode == IW_MODE_MASTER ||
857 local->iw_mode == IW_MODE_REPEAT) &&
858 !from_assoc_ap) {
859 switch (hostap_handle_sta_rx(local, dev, skb, rx_stats,
860 wds != NULL)) {
861 case AP_RX_CONTINUE_NOT_AUTHORIZED:
862 frame_authorized = 0;
863 break;
864 case AP_RX_CONTINUE:
865 frame_authorized = 1;
866 break;
867 case AP_RX_DROP:
868 goto rx_dropped;
869 case AP_RX_EXIT:
870 goto rx_exit;
871 }
872 }
873
874 /* Nullfunc frames may have PS-bit set, so they must be passed to
875 * hostap_handle_sta_rx() before being dropped here. */
876 if (stype != IEEE80211_STYPE_DATA &&
877 stype != IEEE80211_STYPE_DATA_CFACK &&
878 stype != IEEE80211_STYPE_DATA_CFPOLL &&
879 stype != IEEE80211_STYPE_DATA_CFACKPOLL) {
880 if (stype != IEEE80211_STYPE_NULLFUNC)
881 printk(KERN_DEBUG "%s: RX: dropped data frame "
882 "with no data (type=0x%02x, subtype=0x%02x)\n",
883 dev->name, type >> 2, stype >> 4);
884 goto rx_dropped;
885 }
886
887 /* skb: hdr + (possibly fragmented, possibly encrypted) payload */
888
889 if (local->host_decrypt && (fc & IEEE80211_FCTL_PROTECTED) &&
890 (keyidx = hostap_rx_frame_decrypt(local, skb, crypt)) < 0)
891 goto rx_dropped;
892 hdr = (struct ieee80211_hdr *) skb->data;
893
894 /* skb: hdr + (possibly fragmented) plaintext payload */
895
896 if (local->host_decrypt && (fc & IEEE80211_FCTL_PROTECTED) &&
897 (frag != 0 || (fc & IEEE80211_FCTL_MOREFRAGS))) {
898 int flen;
899 struct sk_buff *frag_skb =
900 prism2_frag_cache_get(local, hdr);
901 if (!frag_skb) {
902 printk(KERN_DEBUG "%s: Rx cannot get skb from "
903 "fragment cache (morefrag=%d seq=%u frag=%u)\n",
904 dev->name, (fc & IEEE80211_FCTL_MOREFRAGS) != 0,
905 WLAN_GET_SEQ_SEQ(sc) >> 4, frag);
906 goto rx_dropped;
907 }
908
909 flen = skb->len;
910 if (frag != 0)
911 flen -= hdrlen;
912
913 if (frag_skb->tail + flen > frag_skb->end) {
914 printk(KERN_WARNING "%s: host decrypted and "
915 "reassembled frame did not fit skb\n",
916 dev->name);
917 prism2_frag_cache_invalidate(local, hdr);
918 goto rx_dropped;
919 }
920
921 if (frag == 0) {
922 /* copy first fragment (including full headers) into
923 * beginning of the fragment cache skb */
924 memcpy(skb_put(frag_skb, flen), skb->data, flen);
925 } else {
926 /* append frame payload to the end of the fragment
927 * cache skb */
928 memcpy(skb_put(frag_skb, flen), skb->data + hdrlen,
929 flen);
930 }
931 dev_kfree_skb(skb);
932 skb = NULL;
933
934 if (fc & IEEE80211_FCTL_MOREFRAGS) {
935 /* more fragments expected - leave the skb in fragment
936 * cache for now; it will be delivered to upper layers
937 * after all fragments have been received */
938 goto rx_exit;
939 }
940
941 /* this was the last fragment and the frame will be
942 * delivered, so remove skb from fragment cache */
943 skb = frag_skb;
944 hdr = (struct ieee80211_hdr *) skb->data;
945 prism2_frag_cache_invalidate(local, hdr);
946 }
947
948 /* skb: hdr + (possible reassembled) full MSDU payload; possibly still
949 * encrypted/authenticated */
950
951 if (local->host_decrypt && (fc & IEEE80211_FCTL_PROTECTED) &&
952 hostap_rx_frame_decrypt_msdu(local, skb, keyidx, crypt))
953 goto rx_dropped;
954
955 hdr = (struct ieee80211_hdr *) skb->data;
956 if (crypt && !(fc & IEEE80211_FCTL_PROTECTED) && !local->open_wep) {
957 if (local->ieee_802_1x &&
958 hostap_is_eapol_frame(local, skb)) {
959 /* pass unencrypted EAPOL frames even if encryption is
960 * configured */
961 PDEBUG(DEBUG_EXTRA2, "%s: RX: IEEE 802.1X - passing "
962 "unencrypted EAPOL frame\n", local->dev->name);
963 } else {
964 printk(KERN_DEBUG "%s: encryption configured, but RX "
965 "frame not encrypted (SA=" MACSTR ")\n",
966 local->dev->name, MAC2STR(hdr->addr2));
967 goto rx_dropped;
968 }
969 }
970
971 if (local->drop_unencrypted && !(fc & IEEE80211_FCTL_PROTECTED) &&
972 !hostap_is_eapol_frame(local, skb)) {
973 if (net_ratelimit()) {
974 printk(KERN_DEBUG "%s: dropped unencrypted RX data "
975 "frame from " MACSTR " (drop_unencrypted=1)\n",
976 dev->name, MAC2STR(hdr->addr2));
977 }
978 goto rx_dropped;
979 }
980
981 /* skb: hdr + (possible reassembled) full plaintext payload */
982
983 payload = skb->data + hdrlen;
984 ethertype = (payload[6] << 8) | payload[7];
985
986 /* If IEEE 802.1X is used, check whether the port is authorized to send
987 * the received frame. */
988 if (local->ieee_802_1x && local->iw_mode == IW_MODE_MASTER) {
989 if (ethertype == ETH_P_PAE) {
990 PDEBUG(DEBUG_EXTRA2, "%s: RX: IEEE 802.1X frame\n",
991 dev->name);
992 if (local->hostapd && local->apdev) {
993 /* Send IEEE 802.1X frames to the user
994 * space daemon for processing */
995 prism2_rx_80211(local->apdev, skb, rx_stats,
996 PRISM2_RX_MGMT);
997 local->apdevstats.rx_packets++;
998 local->apdevstats.rx_bytes += skb->len;
999 goto rx_exit;
1000 }
1001 } else if (!frame_authorized) {
1002 printk(KERN_DEBUG "%s: dropped frame from "
1003 "unauthorized port (IEEE 802.1X): "
1004 "ethertype=0x%04x\n",
1005 dev->name, ethertype);
1006 goto rx_dropped;
1007 }
1008 }
1009
1010 /* convert hdr + possible LLC headers into Ethernet header */
1011 if (skb->len - hdrlen >= 8 &&
1012 ((memcmp(payload, rfc1042_header, 6) == 0 &&
1013 ethertype != ETH_P_AARP && ethertype != ETH_P_IPX) ||
1014 memcmp(payload, bridge_tunnel_header, 6) == 0)) {
1015 /* remove RFC1042 or Bridge-Tunnel encapsulation and
1016 * replace EtherType */
1017 skb_pull(skb, hdrlen + 6);
1018 memcpy(skb_push(skb, ETH_ALEN), src, ETH_ALEN);
1019 memcpy(skb_push(skb, ETH_ALEN), dst, ETH_ALEN);
1020 } else {
1021 u16 len;
1022 /* Leave Ethernet header part of hdr and full payload */
1023 skb_pull(skb, hdrlen);
1024 len = htons(skb->len);
1025 memcpy(skb_push(skb, 2), &len, 2);
1026 memcpy(skb_push(skb, ETH_ALEN), src, ETH_ALEN);
1027 memcpy(skb_push(skb, ETH_ALEN), dst, ETH_ALEN);
1028 }
1029
1030 if (wds && ((fc & (IEEE80211_FCTL_TODS | IEEE80211_FCTL_FROMDS)) ==
1031 IEEE80211_FCTL_TODS) &&
1032 skb->len >= ETH_HLEN + ETH_ALEN) {
1033 /* Non-standard frame: get addr4 from its bogus location after
1034 * the payload */
1035 memcpy(skb->data + ETH_ALEN,
1036 skb->data + skb->len - ETH_ALEN, ETH_ALEN);
1037 skb_trim(skb, skb->len - ETH_ALEN);
1038 }
1039
1040 stats->rx_packets++;
1041 stats->rx_bytes += skb->len;
1042
1043 if (local->iw_mode == IW_MODE_MASTER && !wds &&
1044 local->ap->bridge_packets) {
1045 if (dst[0] & 0x01) {
1046 /* copy multicast frame both to the higher layers and
1047 * to the wireless media */
1048 local->ap->bridged_multicast++;
1049 skb2 = skb_clone(skb, GFP_ATOMIC);
1050 if (skb2 == NULL)
1051 printk(KERN_DEBUG "%s: skb_clone failed for "
1052 "multicast frame\n", dev->name);
1053 } else if (hostap_is_sta_authorized(local->ap, dst)) {
1054 /* send frame directly to the associated STA using
1055 * wireless media and not passing to higher layers */
1056 local->ap->bridged_unicast++;
1057 skb2 = skb;
1058 skb = NULL;
1059 }
1060 }
1061
1062 if (skb2 != NULL) {
1063 /* send to wireless media */
1064 skb2->protocol = __constant_htons(ETH_P_802_3);
1065 skb2->mac.raw = skb2->nh.raw = skb2->data;
1066 /* skb2->nh.raw = skb2->data + ETH_HLEN; */
1067 skb2->dev = dev;
1068 dev_queue_xmit(skb2);
1069 }
1070
1071 if (skb) {
1072 skb->protocol = eth_type_trans(skb, dev);
1073 memset(skb->cb, 0, sizeof(skb->cb));
1074 skb->dev = dev;
1075 netif_rx(skb);
1076 }
1077
1078 rx_exit:
1079 if (sta)
1080 hostap_handle_sta_release(sta);
1081 return;
1082
1083 rx_dropped:
1084 dev_kfree_skb(skb);
1085
1086 stats->rx_dropped++;
1087 goto rx_exit;
1088}
1089
1090
1091EXPORT_SYMBOL(hostap_80211_rx);
diff --git a/drivers/net/wireless/hostap/hostap_80211_tx.c b/drivers/net/wireless/hostap/hostap_80211_tx.c
new file mode 100644
index 000000000000..6358015f6526
--- /dev/null
+++ b/drivers/net/wireless/hostap/hostap_80211_tx.c
@@ -0,0 +1,524 @@
1void hostap_dump_tx_80211(const char *name, struct sk_buff *skb)
2{
3 struct ieee80211_hdr *hdr;
4 u16 fc;
5
6 hdr = (struct ieee80211_hdr *) skb->data;
7
8 printk(KERN_DEBUG "%s: TX len=%d jiffies=%ld\n",
9 name, skb->len, jiffies);
10
11 if (skb->len < 2)
12 return;
13
14 fc = le16_to_cpu(hdr->frame_ctl);
15 printk(KERN_DEBUG " FC=0x%04x (type=%d:%d)%s%s",
16 fc, WLAN_FC_GET_TYPE(fc) >> 2, WLAN_FC_GET_STYPE(fc) >> 4,
17 fc & IEEE80211_FCTL_TODS ? " [ToDS]" : "",
18 fc & IEEE80211_FCTL_FROMDS ? " [FromDS]" : "");
19
20 if (skb->len < IEEE80211_DATA_HDR3_LEN) {
21 printk("\n");
22 return;
23 }
24
25 printk(" dur=0x%04x seq=0x%04x\n", le16_to_cpu(hdr->duration_id),
26 le16_to_cpu(hdr->seq_ctl));
27
28 printk(KERN_DEBUG " A1=" MACSTR " A2=" MACSTR " A3=" MACSTR,
29 MAC2STR(hdr->addr1), MAC2STR(hdr->addr2), MAC2STR(hdr->addr3));
30 if (skb->len >= 30)
31 printk(" A4=" MACSTR, MAC2STR(hdr->addr4));
32 printk("\n");
33}
34
35
36/* hard_start_xmit function for data interfaces (wlan#, wlan#wds#, wlan#sta)
37 * Convert Ethernet header into a suitable IEEE 802.11 header depending on
38 * device configuration. */
39int hostap_data_start_xmit(struct sk_buff *skb, struct net_device *dev)
40{
41 struct hostap_interface *iface;
42 local_info_t *local;
43 int need_headroom, need_tailroom = 0;
44 struct ieee80211_hdr hdr;
45 u16 fc, ethertype = 0;
46 enum {
47 WDS_NO = 0, WDS_OWN_FRAME, WDS_COMPLIANT_FRAME
48 } use_wds = WDS_NO;
49 u8 *encaps_data;
50 int hdr_len, encaps_len, skip_header_bytes;
51 int to_assoc_ap = 0;
52 struct hostap_skb_tx_data *meta;
53
54 iface = netdev_priv(dev);
55 local = iface->local;
56
57 if (skb->len < ETH_HLEN) {
58 printk(KERN_DEBUG "%s: hostap_data_start_xmit: short skb "
59 "(len=%d)\n", dev->name, skb->len);
60 kfree_skb(skb);
61 return 0;
62 }
63
64 if (local->ddev != dev) {
65 use_wds = (local->iw_mode == IW_MODE_MASTER &&
66 !(local->wds_type & HOSTAP_WDS_STANDARD_FRAME)) ?
67 WDS_OWN_FRAME : WDS_COMPLIANT_FRAME;
68 if (dev == local->stadev) {
69 to_assoc_ap = 1;
70 use_wds = WDS_NO;
71 } else if (dev == local->apdev) {
72 printk(KERN_DEBUG "%s: prism2_tx: trying to use "
73 "AP device with Ethernet net dev\n", dev->name);
74 kfree_skb(skb);
75 return 0;
76 }
77 } else {
78 if (local->iw_mode == IW_MODE_REPEAT) {
79 printk(KERN_DEBUG "%s: prism2_tx: trying to use "
80 "non-WDS link in Repeater mode\n", dev->name);
81 kfree_skb(skb);
82 return 0;
83 } else if (local->iw_mode == IW_MODE_INFRA &&
84 (local->wds_type & HOSTAP_WDS_AP_CLIENT) &&
85 memcmp(skb->data + ETH_ALEN, dev->dev_addr,
86 ETH_ALEN) != 0) {
87 /* AP client mode: send frames with foreign src addr
88 * using 4-addr WDS frames */
89 use_wds = WDS_COMPLIANT_FRAME;
90 }
91 }
92
93 /* Incoming skb->data: dst_addr[6], src_addr[6], proto[2], payload
94 * ==>
95 * Prism2 TX frame with 802.11 header:
96 * txdesc (address order depending on used mode; includes dst_addr and
97 * src_addr), possible encapsulation (RFC1042/Bridge-Tunnel;
98 * proto[2], payload {, possible addr4[6]} */
99
100 ethertype = (skb->data[12] << 8) | skb->data[13];
101
102 memset(&hdr, 0, sizeof(hdr));
103
104 /* Length of data after IEEE 802.11 header */
105 encaps_data = NULL;
106 encaps_len = 0;
107 skip_header_bytes = ETH_HLEN;
108 if (ethertype == ETH_P_AARP || ethertype == ETH_P_IPX) {
109 encaps_data = bridge_tunnel_header;
110 encaps_len = sizeof(bridge_tunnel_header);
111 skip_header_bytes -= 2;
112 } else if (ethertype >= 0x600) {
113 encaps_data = rfc1042_header;
114 encaps_len = sizeof(rfc1042_header);
115 skip_header_bytes -= 2;
116 }
117
118 fc = IEEE80211_FTYPE_DATA | IEEE80211_STYPE_DATA;
119 hdr_len = IEEE80211_DATA_HDR3_LEN;
120
121 if (use_wds != WDS_NO) {
122 /* Note! Prism2 station firmware has problems with sending real
123 * 802.11 frames with four addresses; until these problems can
124 * be fixed or worked around, 4-addr frames needed for WDS are
125 * using incompatible format: FromDS flag is not set and the
126 * fourth address is added after the frame payload; it is
127 * assumed, that the receiving station knows how to handle this
128 * frame format */
129
130 if (use_wds == WDS_COMPLIANT_FRAME) {
131 fc |= IEEE80211_FCTL_FROMDS | IEEE80211_FCTL_TODS;
132 /* From&To DS: Addr1 = RA, Addr2 = TA, Addr3 = DA,
133 * Addr4 = SA */
134 memcpy(&hdr.addr4, skb->data + ETH_ALEN, ETH_ALEN);
135 hdr_len += ETH_ALEN;
136 } else {
137 /* bogus 4-addr format to workaround Prism2 station
138 * f/w bug */
139 fc |= IEEE80211_FCTL_TODS;
140 /* From DS: Addr1 = DA (used as RA),
141 * Addr2 = BSSID (used as TA), Addr3 = SA (used as DA),
142 */
143
144 /* SA from skb->data + ETH_ALEN will be added after
145 * frame payload; use hdr.addr4 as a temporary buffer
146 */
147 memcpy(&hdr.addr4, skb->data + ETH_ALEN, ETH_ALEN);
148 need_tailroom += ETH_ALEN;
149 }
150
151 /* send broadcast and multicast frames to broadcast RA, if
152 * configured; otherwise, use unicast RA of the WDS link */
153 if ((local->wds_type & HOSTAP_WDS_BROADCAST_RA) &&
154 skb->data[0] & 0x01)
155 memset(&hdr.addr1, 0xff, ETH_ALEN);
156 else if (iface->type == HOSTAP_INTERFACE_WDS)
157 memcpy(&hdr.addr1, iface->u.wds.remote_addr,
158 ETH_ALEN);
159 else
160 memcpy(&hdr.addr1, local->bssid, ETH_ALEN);
161 memcpy(&hdr.addr2, dev->dev_addr, ETH_ALEN);
162 memcpy(&hdr.addr3, skb->data, ETH_ALEN);
163 } else if (local->iw_mode == IW_MODE_MASTER && !to_assoc_ap) {
164 fc |= IEEE80211_FCTL_FROMDS;
165 /* From DS: Addr1 = DA, Addr2 = BSSID, Addr3 = SA */
166 memcpy(&hdr.addr1, skb->data, ETH_ALEN);
167 memcpy(&hdr.addr2, dev->dev_addr, ETH_ALEN);
168 memcpy(&hdr.addr3, skb->data + ETH_ALEN, ETH_ALEN);
169 } else if (local->iw_mode == IW_MODE_INFRA || to_assoc_ap) {
170 fc |= IEEE80211_FCTL_TODS;
171 /* To DS: Addr1 = BSSID, Addr2 = SA, Addr3 = DA */
172 memcpy(&hdr.addr1, to_assoc_ap ?
173 local->assoc_ap_addr : local->bssid, ETH_ALEN);
174 memcpy(&hdr.addr2, skb->data + ETH_ALEN, ETH_ALEN);
175 memcpy(&hdr.addr3, skb->data, ETH_ALEN);
176 } else if (local->iw_mode == IW_MODE_ADHOC) {
177 /* not From/To DS: Addr1 = DA, Addr2 = SA, Addr3 = BSSID */
178 memcpy(&hdr.addr1, skb->data, ETH_ALEN);
179 memcpy(&hdr.addr2, skb->data + ETH_ALEN, ETH_ALEN);
180 memcpy(&hdr.addr3, local->bssid, ETH_ALEN);
181 }
182
183 hdr.frame_ctl = cpu_to_le16(fc);
184
185 skb_pull(skb, skip_header_bytes);
186 need_headroom = local->func->need_tx_headroom + hdr_len + encaps_len;
187 if (skb_tailroom(skb) < need_tailroom) {
188 skb = skb_unshare(skb, GFP_ATOMIC);
189 if (skb == NULL) {
190 iface->stats.tx_dropped++;
191 return 0;
192 }
193 if (pskb_expand_head(skb, need_headroom, need_tailroom,
194 GFP_ATOMIC)) {
195 kfree_skb(skb);
196 iface->stats.tx_dropped++;
197 return 0;
198 }
199 } else if (skb_headroom(skb) < need_headroom) {
200 struct sk_buff *tmp = skb;
201 skb = skb_realloc_headroom(skb, need_headroom);
202 kfree_skb(tmp);
203 if (skb == NULL) {
204 iface->stats.tx_dropped++;
205 return 0;
206 }
207 } else {
208 skb = skb_unshare(skb, GFP_ATOMIC);
209 if (skb == NULL) {
210 iface->stats.tx_dropped++;
211 return 0;
212 }
213 }
214
215 if (encaps_data)
216 memcpy(skb_push(skb, encaps_len), encaps_data, encaps_len);
217 memcpy(skb_push(skb, hdr_len), &hdr, hdr_len);
218 if (use_wds == WDS_OWN_FRAME) {
219 memcpy(skb_put(skb, ETH_ALEN), &hdr.addr4, ETH_ALEN);
220 }
221
222 iface->stats.tx_packets++;
223 iface->stats.tx_bytes += skb->len;
224
225 skb->mac.raw = skb->data;
226 meta = (struct hostap_skb_tx_data *) skb->cb;
227 memset(meta, 0, sizeof(*meta));
228 meta->magic = HOSTAP_SKB_TX_DATA_MAGIC;
229 if (use_wds)
230 meta->flags |= HOSTAP_TX_FLAGS_WDS;
231 meta->ethertype = ethertype;
232 meta->iface = iface;
233
234 /* Send IEEE 802.11 encapsulated frame using the master radio device */
235 skb->dev = local->dev;
236 dev_queue_xmit(skb);
237 return 0;
238}
239
240
241/* hard_start_xmit function for hostapd wlan#ap interfaces */
242int hostap_mgmt_start_xmit(struct sk_buff *skb, struct net_device *dev)
243{
244 struct hostap_interface *iface;
245 local_info_t *local;
246 struct hostap_skb_tx_data *meta;
247 struct ieee80211_hdr *hdr;
248 u16 fc;
249
250 iface = netdev_priv(dev);
251 local = iface->local;
252
253 if (skb->len < 10) {
254 printk(KERN_DEBUG "%s: hostap_mgmt_start_xmit: short skb "
255 "(len=%d)\n", dev->name, skb->len);
256 kfree_skb(skb);
257 return 0;
258 }
259
260 iface->stats.tx_packets++;
261 iface->stats.tx_bytes += skb->len;
262
263 meta = (struct hostap_skb_tx_data *) skb->cb;
264 memset(meta, 0, sizeof(*meta));
265 meta->magic = HOSTAP_SKB_TX_DATA_MAGIC;
266 meta->iface = iface;
267
268 if (skb->len >= IEEE80211_DATA_HDR3_LEN + sizeof(rfc1042_header) + 2) {
269 hdr = (struct ieee80211_hdr *) skb->data;
270 fc = le16_to_cpu(hdr->frame_ctl);
271 if (WLAN_FC_GET_TYPE(fc) == IEEE80211_FTYPE_DATA &&
272 WLAN_FC_GET_STYPE(fc) == IEEE80211_STYPE_DATA) {
273 u8 *pos = &skb->data[IEEE80211_DATA_HDR3_LEN +
274 sizeof(rfc1042_header)];
275 meta->ethertype = (pos[0] << 8) | pos[1];
276 }
277 }
278
279 /* Send IEEE 802.11 encapsulated frame using the master radio device */
280 skb->dev = local->dev;
281 dev_queue_xmit(skb);
282 return 0;
283}
284
285
286/* Called only from software IRQ */
287struct sk_buff * hostap_tx_encrypt(struct sk_buff *skb,
288 struct ieee80211_crypt_data *crypt)
289{
290 struct hostap_interface *iface;
291 local_info_t *local;
292 struct ieee80211_hdr *hdr;
293 u16 fc;
294 int hdr_len, res;
295
296 iface = netdev_priv(skb->dev);
297 local = iface->local;
298
299 if (skb->len < IEEE80211_DATA_HDR3_LEN) {
300 kfree_skb(skb);
301 return NULL;
302 }
303
304 if (local->tkip_countermeasures &&
305 crypt && crypt->ops && strcmp(crypt->ops->name, "TKIP") == 0) {
306 hdr = (struct ieee80211_hdr *) skb->data;
307 if (net_ratelimit()) {
308 printk(KERN_DEBUG "%s: TKIP countermeasures: dropped "
309 "TX packet to " MACSTR "\n",
310 local->dev->name, MAC2STR(hdr->addr1));
311 }
312 kfree_skb(skb);
313 return NULL;
314 }
315
316 skb = skb_unshare(skb, GFP_ATOMIC);
317 if (skb == NULL)
318 return NULL;
319
320 if ((skb_headroom(skb) < crypt->ops->extra_prefix_len ||
321 skb_tailroom(skb) < crypt->ops->extra_postfix_len) &&
322 pskb_expand_head(skb, crypt->ops->extra_prefix_len,
323 crypt->ops->extra_postfix_len, GFP_ATOMIC)) {
324 kfree_skb(skb);
325 return NULL;
326 }
327
328 hdr = (struct ieee80211_hdr *) skb->data;
329 fc = le16_to_cpu(hdr->frame_ctl);
330 hdr_len = hostap_80211_get_hdrlen(fc);
331
332 /* Host-based IEEE 802.11 fragmentation for TX is not yet supported, so
333 * call both MSDU and MPDU encryption functions from here. */
334 atomic_inc(&crypt->refcnt);
335 res = 0;
336 if (crypt->ops->encrypt_msdu)
337 res = crypt->ops->encrypt_msdu(skb, hdr_len, crypt->priv);
338 if (res == 0 && crypt->ops->encrypt_mpdu)
339 res = crypt->ops->encrypt_mpdu(skb, hdr_len, crypt->priv);
340 atomic_dec(&crypt->refcnt);
341 if (res < 0) {
342 kfree_skb(skb);
343 return NULL;
344 }
345
346 return skb;
347}
348
349
350/* hard_start_xmit function for master radio interface wifi#.
351 * AP processing (TX rate control, power save buffering, etc.).
352 * Use hardware TX function to send the frame. */
353int hostap_master_start_xmit(struct sk_buff *skb, struct net_device *dev)
354{
355 struct hostap_interface *iface;
356 local_info_t *local;
357 int ret = 1;
358 u16 fc;
359 struct hostap_tx_data tx;
360 ap_tx_ret tx_ret;
361 struct hostap_skb_tx_data *meta;
362 int no_encrypt = 0;
363 struct ieee80211_hdr *hdr;
364
365 iface = netdev_priv(dev);
366 local = iface->local;
367
368 tx.skb = skb;
369 tx.sta_ptr = NULL;
370
371 meta = (struct hostap_skb_tx_data *) skb->cb;
372 if (meta->magic != HOSTAP_SKB_TX_DATA_MAGIC) {
373 printk(KERN_DEBUG "%s: invalid skb->cb magic (0x%08x, "
374 "expected 0x%08x)\n",
375 dev->name, meta->magic, HOSTAP_SKB_TX_DATA_MAGIC);
376 ret = 0;
377 iface->stats.tx_dropped++;
378 goto fail;
379 }
380
381 if (local->host_encrypt) {
382 /* Set crypt to default algorithm and key; will be replaced in
383 * AP code if STA has own alg/key */
384 tx.crypt = local->crypt[local->tx_keyidx];
385 tx.host_encrypt = 1;
386 } else {
387 tx.crypt = NULL;
388 tx.host_encrypt = 0;
389 }
390
391 if (skb->len < 24) {
392 printk(KERN_DEBUG "%s: hostap_master_start_xmit: short skb "
393 "(len=%d)\n", dev->name, skb->len);
394 ret = 0;
395 iface->stats.tx_dropped++;
396 goto fail;
397 }
398
399 /* FIX (?):
400 * Wi-Fi 802.11b test plan suggests that AP should ignore power save
401 * bit in authentication and (re)association frames and assume tha
402 * STA remains awake for the response. */
403 tx_ret = hostap_handle_sta_tx(local, &tx);
404 skb = tx.skb;
405 meta = (struct hostap_skb_tx_data *) skb->cb;
406 hdr = (struct ieee80211_hdr *) skb->data;
407 fc = le16_to_cpu(hdr->frame_ctl);
408 switch (tx_ret) {
409 case AP_TX_CONTINUE:
410 break;
411 case AP_TX_CONTINUE_NOT_AUTHORIZED:
412 if (local->ieee_802_1x &&
413 WLAN_FC_GET_TYPE(fc) == IEEE80211_FTYPE_DATA &&
414 meta->ethertype != ETH_P_PAE &&
415 !(meta->flags & HOSTAP_TX_FLAGS_WDS)) {
416 printk(KERN_DEBUG "%s: dropped frame to unauthorized "
417 "port (IEEE 802.1X): ethertype=0x%04x\n",
418 dev->name, meta->ethertype);
419 hostap_dump_tx_80211(dev->name, skb);
420
421 ret = 0; /* drop packet */
422 iface->stats.tx_dropped++;
423 goto fail;
424 }
425 break;
426 case AP_TX_DROP:
427 ret = 0; /* drop packet */
428 iface->stats.tx_dropped++;
429 goto fail;
430 case AP_TX_RETRY:
431 goto fail;
432 case AP_TX_BUFFERED:
433 /* do not free skb here, it will be freed when the
434 * buffered frame is sent/timed out */
435 ret = 0;
436 goto tx_exit;
437 }
438
439 /* Request TX callback if protocol version is 2 in 802.11 header;
440 * this version 2 is a special case used between hostapd and kernel
441 * driver */
442 if (((fc & IEEE80211_FCTL_VERS) == BIT(1)) &&
443 local->ap && local->ap->tx_callback_idx && meta->tx_cb_idx == 0) {
444 meta->tx_cb_idx = local->ap->tx_callback_idx;
445
446 /* remove special version from the frame header */
447 fc &= ~IEEE80211_FCTL_VERS;
448 hdr->frame_ctl = cpu_to_le16(fc);
449 }
450
451 if (WLAN_FC_GET_TYPE(fc) != IEEE80211_FTYPE_DATA) {
452 no_encrypt = 1;
453 tx.crypt = NULL;
454 }
455
456 if (local->ieee_802_1x && meta->ethertype == ETH_P_PAE && tx.crypt &&
457 !(fc & IEEE80211_FCTL_VERS)) {
458 no_encrypt = 1;
459 PDEBUG(DEBUG_EXTRA2, "%s: TX: IEEE 802.1X - passing "
460 "unencrypted EAPOL frame\n", dev->name);
461 tx.crypt = NULL; /* no encryption for IEEE 802.1X frames */
462 }
463
464 if (tx.crypt && (!tx.crypt->ops || !tx.crypt->ops->encrypt_mpdu))
465 tx.crypt = NULL;
466 else if ((tx.crypt || local->crypt[local->tx_keyidx]) && !no_encrypt) {
467 /* Add ISWEP flag both for firmware and host based encryption
468 */
469 fc |= IEEE80211_FCTL_PROTECTED;
470 hdr->frame_ctl = cpu_to_le16(fc);
471 } else if (local->drop_unencrypted &&
472 WLAN_FC_GET_TYPE(fc) == IEEE80211_FTYPE_DATA &&
473 meta->ethertype != ETH_P_PAE) {
474 if (net_ratelimit()) {
475 printk(KERN_DEBUG "%s: dropped unencrypted TX data "
476 "frame (drop_unencrypted=1)\n", dev->name);
477 }
478 iface->stats.tx_dropped++;
479 ret = 0;
480 goto fail;
481 }
482
483 if (tx.crypt) {
484 skb = hostap_tx_encrypt(skb, tx.crypt);
485 if (skb == NULL) {
486 printk(KERN_DEBUG "%s: TX - encryption failed\n",
487 dev->name);
488 ret = 0;
489 goto fail;
490 }
491 meta = (struct hostap_skb_tx_data *) skb->cb;
492 if (meta->magic != HOSTAP_SKB_TX_DATA_MAGIC) {
493 printk(KERN_DEBUG "%s: invalid skb->cb magic (0x%08x, "
494 "expected 0x%08x) after hostap_tx_encrypt\n",
495 dev->name, meta->magic,
496 HOSTAP_SKB_TX_DATA_MAGIC);
497 ret = 0;
498 iface->stats.tx_dropped++;
499 goto fail;
500 }
501 }
502
503 if (local->func->tx == NULL || local->func->tx(skb, dev)) {
504 ret = 0;
505 iface->stats.tx_dropped++;
506 } else {
507 ret = 0;
508 iface->stats.tx_packets++;
509 iface->stats.tx_bytes += skb->len;
510 }
511
512 fail:
513 if (!ret && skb)
514 dev_kfree_skb(skb);
515 tx_exit:
516 if (tx.sta_ptr)
517 hostap_handle_sta_release(tx.sta_ptr);
518 return ret;
519}
520
521
522EXPORT_SYMBOL(hostap_dump_tx_80211);
523EXPORT_SYMBOL(hostap_tx_encrypt);
524EXPORT_SYMBOL(hostap_master_start_xmit);
diff --git a/drivers/net/wireless/hostap/hostap_ap.c b/drivers/net/wireless/hostap/hostap_ap.c
new file mode 100644
index 000000000000..930cef8367f2
--- /dev/null
+++ b/drivers/net/wireless/hostap/hostap_ap.c
@@ -0,0 +1,3288 @@
1/*
2 * Intersil Prism2 driver with Host AP (software access point) support
3 * Copyright (c) 2001-2002, SSH Communications Security Corp and Jouni Malinen
4 * <jkmaline@cc.hut.fi>
5 * Copyright (c) 2002-2005, Jouni Malinen <jkmaline@cc.hut.fi>
6 *
7 * This file is to be included into hostap.c when S/W AP functionality is
8 * compiled.
9 *
10 * AP: FIX:
11 * - if unicast Class 2 (assoc,reassoc,disassoc) frame received from
12 * unauthenticated STA, send deauth. frame (8802.11: 5.5)
13 * - if unicast Class 3 (data with to/from DS,deauth,pspoll) frame received
14 * from authenticated, but unassoc STA, send disassoc frame (8802.11: 5.5)
15 * - if unicast Class 3 received from unauthenticated STA, send deauth. frame
16 * (8802.11: 5.5)
17 */
18
19static int other_ap_policy[MAX_PARM_DEVICES] = { AP_OTHER_AP_SKIP_ALL,
20 DEF_INTS };
21module_param_array(other_ap_policy, int, NULL, 0444);
22MODULE_PARM_DESC(other_ap_policy, "Other AP beacon monitoring policy (0-3)");
23
24static int ap_max_inactivity[MAX_PARM_DEVICES] = { AP_MAX_INACTIVITY_SEC,
25 DEF_INTS };
26module_param_array(ap_max_inactivity, int, NULL, 0444);
27MODULE_PARM_DESC(ap_max_inactivity, "AP timeout (in seconds) for station "
28 "inactivity");
29
30static int ap_bridge_packets[MAX_PARM_DEVICES] = { 1, DEF_INTS };
31module_param_array(ap_bridge_packets, int, NULL, 0444);
32MODULE_PARM_DESC(ap_bridge_packets, "Bridge packets directly between "
33 "stations");
34
35static int autom_ap_wds[MAX_PARM_DEVICES] = { 0, DEF_INTS };
36module_param_array(autom_ap_wds, int, NULL, 0444);
37MODULE_PARM_DESC(autom_ap_wds, "Add WDS connections to other APs "
38 "automatically");
39
40
41static struct sta_info* ap_get_sta(struct ap_data *ap, u8 *sta);
42static void hostap_event_expired_sta(struct net_device *dev,
43 struct sta_info *sta);
44static void handle_add_proc_queue(void *data);
45
46#ifndef PRISM2_NO_KERNEL_IEEE80211_MGMT
47static void handle_wds_oper_queue(void *data);
48static void prism2_send_mgmt(struct net_device *dev,
49 u16 type_subtype, char *body,
50 int body_len, u8 *addr, u16 tx_cb_idx);
51#endif /* PRISM2_NO_KERNEL_IEEE80211_MGMT */
52
53
54#ifndef PRISM2_NO_PROCFS_DEBUG
55static int ap_debug_proc_read(char *page, char **start, off_t off,
56 int count, int *eof, void *data)
57{
58 char *p = page;
59 struct ap_data *ap = (struct ap_data *) data;
60
61 if (off != 0) {
62 *eof = 1;
63 return 0;
64 }
65
66 p += sprintf(p, "BridgedUnicastFrames=%u\n", ap->bridged_unicast);
67 p += sprintf(p, "BridgedMulticastFrames=%u\n", ap->bridged_multicast);
68 p += sprintf(p, "max_inactivity=%u\n", ap->max_inactivity / HZ);
69 p += sprintf(p, "bridge_packets=%u\n", ap->bridge_packets);
70 p += sprintf(p, "nullfunc_ack=%u\n", ap->nullfunc_ack);
71 p += sprintf(p, "autom_ap_wds=%u\n", ap->autom_ap_wds);
72 p += sprintf(p, "auth_algs=%u\n", ap->local->auth_algs);
73 p += sprintf(p, "tx_drop_nonassoc=%u\n", ap->tx_drop_nonassoc);
74
75 return (p - page);
76}
77#endif /* PRISM2_NO_PROCFS_DEBUG */
78
79
80static void ap_sta_hash_add(struct ap_data *ap, struct sta_info *sta)
81{
82 sta->hnext = ap->sta_hash[STA_HASH(sta->addr)];
83 ap->sta_hash[STA_HASH(sta->addr)] = sta;
84}
85
86static void ap_sta_hash_del(struct ap_data *ap, struct sta_info *sta)
87{
88 struct sta_info *s;
89
90 s = ap->sta_hash[STA_HASH(sta->addr)];
91 if (s == NULL) return;
92 if (memcmp(s->addr, sta->addr, ETH_ALEN) == 0) {
93 ap->sta_hash[STA_HASH(sta->addr)] = s->hnext;
94 return;
95 }
96
97 while (s->hnext != NULL && memcmp(s->hnext->addr, sta->addr, ETH_ALEN)
98 != 0)
99 s = s->hnext;
100 if (s->hnext != NULL)
101 s->hnext = s->hnext->hnext;
102 else
103 printk("AP: could not remove STA " MACSTR " from hash table\n",
104 MAC2STR(sta->addr));
105}
106
107static void ap_free_sta(struct ap_data *ap, struct sta_info *sta)
108{
109 if (sta->ap && sta->local)
110 hostap_event_expired_sta(sta->local->dev, sta);
111
112 if (ap->proc != NULL) {
113 char name[20];
114 sprintf(name, MACSTR, MAC2STR(sta->addr));
115 remove_proc_entry(name, ap->proc);
116 }
117
118 if (sta->crypt) {
119 sta->crypt->ops->deinit(sta->crypt->priv);
120 kfree(sta->crypt);
121 sta->crypt = NULL;
122 }
123
124 skb_queue_purge(&sta->tx_buf);
125
126 ap->num_sta--;
127#ifndef PRISM2_NO_KERNEL_IEEE80211_MGMT
128 if (sta->aid > 0)
129 ap->sta_aid[sta->aid - 1] = NULL;
130
131 if (!sta->ap && sta->u.sta.challenge)
132 kfree(sta->u.sta.challenge);
133 del_timer(&sta->timer);
134#endif /* PRISM2_NO_KERNEL_IEEE80211_MGMT */
135
136 kfree(sta);
137}
138
139
140static void hostap_set_tim(local_info_t *local, int aid, int set)
141{
142 if (local->func->set_tim)
143 local->func->set_tim(local->dev, aid, set);
144}
145
146
147static void hostap_event_new_sta(struct net_device *dev, struct sta_info *sta)
148{
149 union iwreq_data wrqu;
150 memset(&wrqu, 0, sizeof(wrqu));
151 memcpy(wrqu.addr.sa_data, sta->addr, ETH_ALEN);
152 wrqu.addr.sa_family = ARPHRD_ETHER;
153 wireless_send_event(dev, IWEVREGISTERED, &wrqu, NULL);
154}
155
156
157static void hostap_event_expired_sta(struct net_device *dev,
158 struct sta_info *sta)
159{
160 union iwreq_data wrqu;
161 memset(&wrqu, 0, sizeof(wrqu));
162 memcpy(wrqu.addr.sa_data, sta->addr, ETH_ALEN);
163 wrqu.addr.sa_family = ARPHRD_ETHER;
164 wireless_send_event(dev, IWEVEXPIRED, &wrqu, NULL);
165}
166
167
168#ifndef PRISM2_NO_KERNEL_IEEE80211_MGMT
169
170static void ap_handle_timer(unsigned long data)
171{
172 struct sta_info *sta = (struct sta_info *) data;
173 local_info_t *local;
174 struct ap_data *ap;
175 unsigned long next_time = 0;
176 int was_assoc;
177
178 if (sta == NULL || sta->local == NULL || sta->local->ap == NULL) {
179 PDEBUG(DEBUG_AP, "ap_handle_timer() called with NULL data\n");
180 return;
181 }
182
183 local = sta->local;
184 ap = local->ap;
185 was_assoc = sta->flags & WLAN_STA_ASSOC;
186
187 if (atomic_read(&sta->users) != 0)
188 next_time = jiffies + HZ;
189 else if ((sta->flags & WLAN_STA_PERM) && !(sta->flags & WLAN_STA_AUTH))
190 next_time = jiffies + ap->max_inactivity;
191
192 if (time_before(jiffies, sta->last_rx + ap->max_inactivity)) {
193 /* station activity detected; reset timeout state */
194 sta->timeout_next = STA_NULLFUNC;
195 next_time = sta->last_rx + ap->max_inactivity;
196 } else if (sta->timeout_next == STA_DISASSOC &&
197 !(sta->flags & WLAN_STA_PENDING_POLL)) {
198 /* STA ACKed data nullfunc frame poll */
199 sta->timeout_next = STA_NULLFUNC;
200 next_time = jiffies + ap->max_inactivity;
201 }
202
203 if (next_time) {
204 sta->timer.expires = next_time;
205 add_timer(&sta->timer);
206 return;
207 }
208
209 if (sta->ap)
210 sta->timeout_next = STA_DEAUTH;
211
212 if (sta->timeout_next == STA_DEAUTH && !(sta->flags & WLAN_STA_PERM)) {
213 spin_lock(&ap->sta_table_lock);
214 ap_sta_hash_del(ap, sta);
215 list_del(&sta->list);
216 spin_unlock(&ap->sta_table_lock);
217 sta->flags &= ~(WLAN_STA_AUTH | WLAN_STA_ASSOC);
218 } else if (sta->timeout_next == STA_DISASSOC)
219 sta->flags &= ~WLAN_STA_ASSOC;
220
221 if (was_assoc && !(sta->flags & WLAN_STA_ASSOC) && !sta->ap)
222 hostap_event_expired_sta(local->dev, sta);
223
224 if (sta->timeout_next == STA_DEAUTH && sta->aid > 0 &&
225 !skb_queue_empty(&sta->tx_buf)) {
226 hostap_set_tim(local, sta->aid, 0);
227 sta->flags &= ~WLAN_STA_TIM;
228 }
229
230 if (sta->ap) {
231 if (ap->autom_ap_wds) {
232 PDEBUG(DEBUG_AP, "%s: removing automatic WDS "
233 "connection to AP " MACSTR "\n",
234 local->dev->name, MAC2STR(sta->addr));
235 hostap_wds_link_oper(local, sta->addr, WDS_DEL);
236 }
237 } else if (sta->timeout_next == STA_NULLFUNC) {
238 /* send data frame to poll STA and check whether this frame
239 * is ACKed */
240 /* FIX: IEEE80211_STYPE_NULLFUNC would be more appropriate, but
241 * it is apparently not retried so TX Exc events are not
242 * received for it */
243 sta->flags |= WLAN_STA_PENDING_POLL;
244 prism2_send_mgmt(local->dev, IEEE80211_FTYPE_DATA |
245 IEEE80211_STYPE_DATA, NULL, 0,
246 sta->addr, ap->tx_callback_poll);
247 } else {
248 int deauth = sta->timeout_next == STA_DEAUTH;
249 u16 resp;
250 PDEBUG(DEBUG_AP, "%s: sending %s info to STA " MACSTR
251 "(last=%lu, jiffies=%lu)\n",
252 local->dev->name,
253 deauth ? "deauthentication" : "disassociation",
254 MAC2STR(sta->addr), sta->last_rx, jiffies);
255
256 resp = cpu_to_le16(deauth ? WLAN_REASON_PREV_AUTH_NOT_VALID :
257 WLAN_REASON_DISASSOC_DUE_TO_INACTIVITY);
258 prism2_send_mgmt(local->dev, IEEE80211_FTYPE_MGMT |
259 (deauth ? IEEE80211_STYPE_DEAUTH :
260 IEEE80211_STYPE_DISASSOC),
261 (char *) &resp, 2, sta->addr, 0);
262 }
263
264 if (sta->timeout_next == STA_DEAUTH) {
265 if (sta->flags & WLAN_STA_PERM) {
266 PDEBUG(DEBUG_AP, "%s: STA " MACSTR " would have been "
267 "removed, but it has 'perm' flag\n",
268 local->dev->name, MAC2STR(sta->addr));
269 } else
270 ap_free_sta(ap, sta);
271 return;
272 }
273
274 if (sta->timeout_next == STA_NULLFUNC) {
275 sta->timeout_next = STA_DISASSOC;
276 sta->timer.expires = jiffies + AP_DISASSOC_DELAY;
277 } else {
278 sta->timeout_next = STA_DEAUTH;
279 sta->timer.expires = jiffies + AP_DEAUTH_DELAY;
280 }
281
282 add_timer(&sta->timer);
283}
284
285
286void hostap_deauth_all_stas(struct net_device *dev, struct ap_data *ap,
287 int resend)
288{
289 u8 addr[ETH_ALEN];
290 u16 resp;
291 int i;
292
293 PDEBUG(DEBUG_AP, "%s: Deauthenticate all stations\n", dev->name);
294 memset(addr, 0xff, ETH_ALEN);
295
296 resp = __constant_cpu_to_le16(WLAN_REASON_PREV_AUTH_NOT_VALID);
297
298 /* deauth message sent; try to resend it few times; the message is
299 * broadcast, so it may be delayed until next DTIM; there is not much
300 * else we can do at this point since the driver is going to be shut
301 * down */
302 for (i = 0; i < 5; i++) {
303 prism2_send_mgmt(dev, IEEE80211_FTYPE_MGMT |
304 IEEE80211_STYPE_DEAUTH,
305 (char *) &resp, 2, addr, 0);
306
307 if (!resend || ap->num_sta <= 0)
308 return;
309
310 mdelay(50);
311 }
312}
313
314
315static int ap_control_proc_read(char *page, char **start, off_t off,
316 int count, int *eof, void *data)
317{
318 char *p = page;
319 struct ap_data *ap = (struct ap_data *) data;
320 char *policy_txt;
321 struct list_head *ptr;
322 struct mac_entry *entry;
323
324 if (off != 0) {
325 *eof = 1;
326 return 0;
327 }
328
329 switch (ap->mac_restrictions.policy) {
330 case MAC_POLICY_OPEN:
331 policy_txt = "open";
332 break;
333 case MAC_POLICY_ALLOW:
334 policy_txt = "allow";
335 break;
336 case MAC_POLICY_DENY:
337 policy_txt = "deny";
338 break;
339 default:
340 policy_txt = "unknown";
341 break;
342 };
343 p += sprintf(p, "MAC policy: %s\n", policy_txt);
344 p += sprintf(p, "MAC entries: %u\n", ap->mac_restrictions.entries);
345 p += sprintf(p, "MAC list:\n");
346 spin_lock_bh(&ap->mac_restrictions.lock);
347 for (ptr = ap->mac_restrictions.mac_list.next;
348 ptr != &ap->mac_restrictions.mac_list; ptr = ptr->next) {
349 if (p - page > PAGE_SIZE - 80) {
350 p += sprintf(p, "All entries did not fit one page.\n");
351 break;
352 }
353
354 entry = list_entry(ptr, struct mac_entry, list);
355 p += sprintf(p, MACSTR "\n", MAC2STR(entry->addr));
356 }
357 spin_unlock_bh(&ap->mac_restrictions.lock);
358
359 return (p - page);
360}
361
362
363static int ap_control_add_mac(struct mac_restrictions *mac_restrictions,
364 u8 *mac)
365{
366 struct mac_entry *entry;
367
368 entry = kmalloc(sizeof(struct mac_entry), GFP_KERNEL);
369 if (entry == NULL)
370 return -1;
371
372 memcpy(entry->addr, mac, ETH_ALEN);
373
374 spin_lock_bh(&mac_restrictions->lock);
375 list_add_tail(&entry->list, &mac_restrictions->mac_list);
376 mac_restrictions->entries++;
377 spin_unlock_bh(&mac_restrictions->lock);
378
379 return 0;
380}
381
382
383static int ap_control_del_mac(struct mac_restrictions *mac_restrictions,
384 u8 *mac)
385{
386 struct list_head *ptr;
387 struct mac_entry *entry;
388
389 spin_lock_bh(&mac_restrictions->lock);
390 for (ptr = mac_restrictions->mac_list.next;
391 ptr != &mac_restrictions->mac_list; ptr = ptr->next) {
392 entry = list_entry(ptr, struct mac_entry, list);
393
394 if (memcmp(entry->addr, mac, ETH_ALEN) == 0) {
395 list_del(ptr);
396 kfree(entry);
397 mac_restrictions->entries--;
398 spin_unlock_bh(&mac_restrictions->lock);
399 return 0;
400 }
401 }
402 spin_unlock_bh(&mac_restrictions->lock);
403 return -1;
404}
405
406
407static int ap_control_mac_deny(struct mac_restrictions *mac_restrictions,
408 u8 *mac)
409{
410 struct list_head *ptr;
411 struct mac_entry *entry;
412 int found = 0;
413
414 if (mac_restrictions->policy == MAC_POLICY_OPEN)
415 return 0;
416
417 spin_lock_bh(&mac_restrictions->lock);
418 for (ptr = mac_restrictions->mac_list.next;
419 ptr != &mac_restrictions->mac_list; ptr = ptr->next) {
420 entry = list_entry(ptr, struct mac_entry, list);
421
422 if (memcmp(entry->addr, mac, ETH_ALEN) == 0) {
423 found = 1;
424 break;
425 }
426 }
427 spin_unlock_bh(&mac_restrictions->lock);
428
429 if (mac_restrictions->policy == MAC_POLICY_ALLOW)
430 return !found;
431 else
432 return found;
433}
434
435
436static void ap_control_flush_macs(struct mac_restrictions *mac_restrictions)
437{
438 struct list_head *ptr, *n;
439 struct mac_entry *entry;
440
441 if (mac_restrictions->entries == 0)
442 return;
443
444 spin_lock_bh(&mac_restrictions->lock);
445 for (ptr = mac_restrictions->mac_list.next, n = ptr->next;
446 ptr != &mac_restrictions->mac_list;
447 ptr = n, n = ptr->next) {
448 entry = list_entry(ptr, struct mac_entry, list);
449 list_del(ptr);
450 kfree(entry);
451 }
452 mac_restrictions->entries = 0;
453 spin_unlock_bh(&mac_restrictions->lock);
454}
455
456
457static int ap_control_kick_mac(struct ap_data *ap, struct net_device *dev,
458 u8 *mac)
459{
460 struct sta_info *sta;
461 u16 resp;
462
463 spin_lock_bh(&ap->sta_table_lock);
464 sta = ap_get_sta(ap, mac);
465 if (sta) {
466 ap_sta_hash_del(ap, sta);
467 list_del(&sta->list);
468 }
469 spin_unlock_bh(&ap->sta_table_lock);
470
471 if (!sta)
472 return -EINVAL;
473
474 resp = cpu_to_le16(WLAN_REASON_PREV_AUTH_NOT_VALID);
475 prism2_send_mgmt(dev, IEEE80211_FTYPE_MGMT | IEEE80211_STYPE_DEAUTH,
476 (char *) &resp, 2, sta->addr, 0);
477
478 if ((sta->flags & WLAN_STA_ASSOC) && !sta->ap)
479 hostap_event_expired_sta(dev, sta);
480
481 ap_free_sta(ap, sta);
482
483 return 0;
484}
485
486#endif /* PRISM2_NO_KERNEL_IEEE80211_MGMT */
487
488
489static void ap_control_kickall(struct ap_data *ap)
490{
491 struct list_head *ptr, *n;
492 struct sta_info *sta;
493
494 spin_lock_bh(&ap->sta_table_lock);
495 for (ptr = ap->sta_list.next, n = ptr->next; ptr != &ap->sta_list;
496 ptr = n, n = ptr->next) {
497 sta = list_entry(ptr, struct sta_info, list);
498 ap_sta_hash_del(ap, sta);
499 list_del(&sta->list);
500 if ((sta->flags & WLAN_STA_ASSOC) && !sta->ap && sta->local)
501 hostap_event_expired_sta(sta->local->dev, sta);
502 ap_free_sta(ap, sta);
503 }
504 spin_unlock_bh(&ap->sta_table_lock);
505}
506
507
508#ifndef PRISM2_NO_KERNEL_IEEE80211_MGMT
509
510#define PROC_LIMIT (PAGE_SIZE - 80)
511
512static int prism2_ap_proc_read(char *page, char **start, off_t off,
513 int count, int *eof, void *data)
514{
515 char *p = page;
516 struct ap_data *ap = (struct ap_data *) data;
517 struct list_head *ptr;
518 int i;
519
520 if (off > PROC_LIMIT) {
521 *eof = 1;
522 return 0;
523 }
524
525 p += sprintf(p, "# BSSID CHAN SIGNAL NOISE RATE SSID FLAGS\n");
526 spin_lock_bh(&ap->sta_table_lock);
527 for (ptr = ap->sta_list.next; ptr != &ap->sta_list; ptr = ptr->next) {
528 struct sta_info *sta = (struct sta_info *) ptr;
529
530 if (!sta->ap)
531 continue;
532
533 p += sprintf(p, MACSTR " %d %d %d %d '", MAC2STR(sta->addr),
534 sta->u.ap.channel, sta->last_rx_signal,
535 sta->last_rx_silence, sta->last_rx_rate);
536 for (i = 0; i < sta->u.ap.ssid_len; i++)
537 p += sprintf(p, ((sta->u.ap.ssid[i] >= 32 &&
538 sta->u.ap.ssid[i] < 127) ?
539 "%c" : "<%02x>"),
540 sta->u.ap.ssid[i]);
541 p += sprintf(p, "'");
542 if (sta->capability & WLAN_CAPABILITY_ESS)
543 p += sprintf(p, " [ESS]");
544 if (sta->capability & WLAN_CAPABILITY_IBSS)
545 p += sprintf(p, " [IBSS]");
546 if (sta->capability & WLAN_CAPABILITY_PRIVACY)
547 p += sprintf(p, " [WEP]");
548 p += sprintf(p, "\n");
549
550 if ((p - page) > PROC_LIMIT) {
551 printk(KERN_DEBUG "hostap: ap proc did not fit\n");
552 break;
553 }
554 }
555 spin_unlock_bh(&ap->sta_table_lock);
556
557 if ((p - page) <= off) {
558 *eof = 1;
559 return 0;
560 }
561
562 *start = page + off;
563
564 return (p - page - off);
565}
566#endif /* PRISM2_NO_KERNEL_IEEE80211_MGMT */
567
568
569void hostap_check_sta_fw_version(struct ap_data *ap, int sta_fw_ver)
570{
571 if (!ap)
572 return;
573
574 if (sta_fw_ver == PRISM2_FW_VER(0,8,0)) {
575 PDEBUG(DEBUG_AP, "Using data::nullfunc ACK workaround - "
576 "firmware upgrade recommended\n");
577 ap->nullfunc_ack = 1;
578 } else
579 ap->nullfunc_ack = 0;
580
581 if (sta_fw_ver == PRISM2_FW_VER(1,4,2)) {
582 printk(KERN_WARNING "%s: Warning: secondary station firmware "
583 "version 1.4.2 does not seem to work in Host AP mode\n",
584 ap->local->dev->name);
585 }
586}
587
588
589/* Called only as a tasklet (software IRQ) */
590static void hostap_ap_tx_cb(struct sk_buff *skb, int ok, void *data)
591{
592 struct ap_data *ap = data;
593 u16 fc;
594 struct ieee80211_hdr *hdr;
595
596 if (!ap->local->hostapd || !ap->local->apdev) {
597 dev_kfree_skb(skb);
598 return;
599 }
600
601 hdr = (struct ieee80211_hdr *) skb->data;
602 fc = le16_to_cpu(hdr->frame_ctl);
603
604 /* Pass the TX callback frame to the hostapd; use 802.11 header version
605 * 1 to indicate failure (no ACK) and 2 success (frame ACKed) */
606
607 fc &= ~IEEE80211_FCTL_VERS;
608 fc |= ok ? BIT(1) : BIT(0);
609 hdr->frame_ctl = cpu_to_le16(fc);
610
611 skb->dev = ap->local->apdev;
612 skb_pull(skb, hostap_80211_get_hdrlen(fc));
613 skb->pkt_type = PACKET_OTHERHOST;
614 skb->protocol = __constant_htons(ETH_P_802_2);
615 memset(skb->cb, 0, sizeof(skb->cb));
616 netif_rx(skb);
617}
618
619
620#ifndef PRISM2_NO_KERNEL_IEEE80211_MGMT
621/* Called only as a tasklet (software IRQ) */
622static void hostap_ap_tx_cb_auth(struct sk_buff *skb, int ok, void *data)
623{
624 struct ap_data *ap = data;
625 struct net_device *dev = ap->local->dev;
626 struct ieee80211_hdr *hdr;
627 u16 fc, *pos, auth_alg, auth_transaction, status;
628 struct sta_info *sta = NULL;
629 char *txt = NULL;
630
631 if (ap->local->hostapd) {
632 dev_kfree_skb(skb);
633 return;
634 }
635
636 hdr = (struct ieee80211_hdr *) skb->data;
637 fc = le16_to_cpu(hdr->frame_ctl);
638 if (WLAN_FC_GET_TYPE(fc) != IEEE80211_FTYPE_MGMT ||
639 WLAN_FC_GET_STYPE(fc) != IEEE80211_STYPE_AUTH ||
640 skb->len < IEEE80211_MGMT_HDR_LEN + 6) {
641 printk(KERN_DEBUG "%s: hostap_ap_tx_cb_auth received invalid "
642 "frame\n", dev->name);
643 dev_kfree_skb(skb);
644 return;
645 }
646
647 pos = (u16 *) (skb->data + IEEE80211_MGMT_HDR_LEN);
648 auth_alg = le16_to_cpu(*pos++);
649 auth_transaction = le16_to_cpu(*pos++);
650 status = le16_to_cpu(*pos++);
651
652 if (!ok) {
653 txt = "frame was not ACKed";
654 goto done;
655 }
656
657 spin_lock(&ap->sta_table_lock);
658 sta = ap_get_sta(ap, hdr->addr1);
659 if (sta)
660 atomic_inc(&sta->users);
661 spin_unlock(&ap->sta_table_lock);
662
663 if (!sta) {
664 txt = "STA not found";
665 goto done;
666 }
667
668 if (status == WLAN_STATUS_SUCCESS &&
669 ((auth_alg == WLAN_AUTH_OPEN && auth_transaction == 2) ||
670 (auth_alg == WLAN_AUTH_SHARED_KEY && auth_transaction == 4))) {
671 txt = "STA authenticated";
672 sta->flags |= WLAN_STA_AUTH;
673 sta->last_auth = jiffies;
674 } else if (status != WLAN_STATUS_SUCCESS)
675 txt = "authentication failed";
676
677 done:
678 if (sta)
679 atomic_dec(&sta->users);
680 if (txt) {
681 PDEBUG(DEBUG_AP, "%s: " MACSTR " auth_cb - alg=%d trans#=%d "
682 "status=%d - %s\n",
683 dev->name, MAC2STR(hdr->addr1), auth_alg,
684 auth_transaction, status, txt);
685 }
686 dev_kfree_skb(skb);
687}
688
689
690/* Called only as a tasklet (software IRQ) */
691static void hostap_ap_tx_cb_assoc(struct sk_buff *skb, int ok, void *data)
692{
693 struct ap_data *ap = data;
694 struct net_device *dev = ap->local->dev;
695 struct ieee80211_hdr *hdr;
696 u16 fc, *pos, status;
697 struct sta_info *sta = NULL;
698 char *txt = NULL;
699
700 if (ap->local->hostapd) {
701 dev_kfree_skb(skb);
702 return;
703 }
704
705 hdr = (struct ieee80211_hdr *) skb->data;
706 fc = le16_to_cpu(hdr->frame_ctl);
707 if (WLAN_FC_GET_TYPE(fc) != IEEE80211_FTYPE_MGMT ||
708 (WLAN_FC_GET_STYPE(fc) != IEEE80211_STYPE_ASSOC_RESP &&
709 WLAN_FC_GET_STYPE(fc) != IEEE80211_STYPE_REASSOC_RESP) ||
710 skb->len < IEEE80211_MGMT_HDR_LEN + 4) {
711 printk(KERN_DEBUG "%s: hostap_ap_tx_cb_assoc received invalid "
712 "frame\n", dev->name);
713 dev_kfree_skb(skb);
714 return;
715 }
716
717 if (!ok) {
718 txt = "frame was not ACKed";
719 goto done;
720 }
721
722 spin_lock(&ap->sta_table_lock);
723 sta = ap_get_sta(ap, hdr->addr1);
724 if (sta)
725 atomic_inc(&sta->users);
726 spin_unlock(&ap->sta_table_lock);
727
728 if (!sta) {
729 txt = "STA not found";
730 goto done;
731 }
732
733 pos = (u16 *) (skb->data + IEEE80211_MGMT_HDR_LEN);
734 pos++;
735 status = le16_to_cpu(*pos++);
736 if (status == WLAN_STATUS_SUCCESS) {
737 if (!(sta->flags & WLAN_STA_ASSOC))
738 hostap_event_new_sta(dev, sta);
739 txt = "STA associated";
740 sta->flags |= WLAN_STA_ASSOC;
741 sta->last_assoc = jiffies;
742 } else
743 txt = "association failed";
744
745 done:
746 if (sta)
747 atomic_dec(&sta->users);
748 if (txt) {
749 PDEBUG(DEBUG_AP, "%s: " MACSTR " assoc_cb - %s\n",
750 dev->name, MAC2STR(hdr->addr1), txt);
751 }
752 dev_kfree_skb(skb);
753}
754
755/* Called only as a tasklet (software IRQ); TX callback for poll frames used
756 * in verifying whether the STA is still present. */
757static void hostap_ap_tx_cb_poll(struct sk_buff *skb, int ok, void *data)
758{
759 struct ap_data *ap = data;
760 struct ieee80211_hdr *hdr;
761 struct sta_info *sta;
762
763 if (skb->len < 24)
764 goto fail;
765 hdr = (struct ieee80211_hdr *) skb->data;
766 if (ok) {
767 spin_lock(&ap->sta_table_lock);
768 sta = ap_get_sta(ap, hdr->addr1);
769 if (sta)
770 sta->flags &= ~WLAN_STA_PENDING_POLL;
771 spin_unlock(&ap->sta_table_lock);
772 } else {
773 PDEBUG(DEBUG_AP, "%s: STA " MACSTR " did not ACK activity "
774 "poll frame\n", ap->local->dev->name,
775 MAC2STR(hdr->addr1));
776 }
777
778 fail:
779 dev_kfree_skb(skb);
780}
781#endif /* PRISM2_NO_KERNEL_IEEE80211_MGMT */
782
783
784void hostap_init_data(local_info_t *local)
785{
786 struct ap_data *ap = local->ap;
787
788 if (ap == NULL) {
789 printk(KERN_WARNING "hostap_init_data: ap == NULL\n");
790 return;
791 }
792 memset(ap, 0, sizeof(struct ap_data));
793 ap->local = local;
794
795 ap->ap_policy = GET_INT_PARM(other_ap_policy, local->card_idx);
796 ap->bridge_packets = GET_INT_PARM(ap_bridge_packets, local->card_idx);
797 ap->max_inactivity =
798 GET_INT_PARM(ap_max_inactivity, local->card_idx) * HZ;
799 ap->autom_ap_wds = GET_INT_PARM(autom_ap_wds, local->card_idx);
800
801 spin_lock_init(&ap->sta_table_lock);
802 INIT_LIST_HEAD(&ap->sta_list);
803
804 /* Initialize task queue structure for AP management */
805 INIT_WORK(&local->ap->add_sta_proc_queue, handle_add_proc_queue, ap);
806
807 ap->tx_callback_idx =
808 hostap_tx_callback_register(local, hostap_ap_tx_cb, ap);
809 if (ap->tx_callback_idx == 0)
810 printk(KERN_WARNING "%s: failed to register TX callback for "
811 "AP\n", local->dev->name);
812#ifndef PRISM2_NO_KERNEL_IEEE80211_MGMT
813 INIT_WORK(&local->ap->wds_oper_queue, handle_wds_oper_queue, local);
814
815 ap->tx_callback_auth =
816 hostap_tx_callback_register(local, hostap_ap_tx_cb_auth, ap);
817 ap->tx_callback_assoc =
818 hostap_tx_callback_register(local, hostap_ap_tx_cb_assoc, ap);
819 ap->tx_callback_poll =
820 hostap_tx_callback_register(local, hostap_ap_tx_cb_poll, ap);
821 if (ap->tx_callback_auth == 0 || ap->tx_callback_assoc == 0 ||
822 ap->tx_callback_poll == 0)
823 printk(KERN_WARNING "%s: failed to register TX callback for "
824 "AP\n", local->dev->name);
825
826 spin_lock_init(&ap->mac_restrictions.lock);
827 INIT_LIST_HEAD(&ap->mac_restrictions.mac_list);
828#endif /* PRISM2_NO_KERNEL_IEEE80211_MGMT */
829
830 ap->initialized = 1;
831}
832
833
834void hostap_init_ap_proc(local_info_t *local)
835{
836 struct ap_data *ap = local->ap;
837
838 ap->proc = local->proc;
839 if (ap->proc == NULL)
840 return;
841
842#ifndef PRISM2_NO_PROCFS_DEBUG
843 create_proc_read_entry("ap_debug", 0, ap->proc,
844 ap_debug_proc_read, ap);
845#endif /* PRISM2_NO_PROCFS_DEBUG */
846
847#ifndef PRISM2_NO_KERNEL_IEEE80211_MGMT
848 create_proc_read_entry("ap_control", 0, ap->proc,
849 ap_control_proc_read, ap);
850 create_proc_read_entry("ap", 0, ap->proc,
851 prism2_ap_proc_read, ap);
852#endif /* PRISM2_NO_KERNEL_IEEE80211_MGMT */
853
854}
855
856
857void hostap_free_data(struct ap_data *ap)
858{
859 struct list_head *n, *ptr;
860
861 if (ap == NULL || !ap->initialized) {
862 printk(KERN_DEBUG "hostap_free_data: ap has not yet been "
863 "initialized - skip resource freeing\n");
864 return;
865 }
866
867#ifndef PRISM2_NO_KERNEL_IEEE80211_MGMT
868 if (ap->crypt)
869 ap->crypt->deinit(ap->crypt_priv);
870 ap->crypt = ap->crypt_priv = NULL;
871#endif /* PRISM2_NO_KERNEL_IEEE80211_MGMT */
872
873 list_for_each_safe(ptr, n, &ap->sta_list) {
874 struct sta_info *sta = list_entry(ptr, struct sta_info, list);
875 ap_sta_hash_del(ap, sta);
876 list_del(&sta->list);
877 if ((sta->flags & WLAN_STA_ASSOC) && !sta->ap && sta->local)
878 hostap_event_expired_sta(sta->local->dev, sta);
879 ap_free_sta(ap, sta);
880 }
881
882#ifndef PRISM2_NO_PROCFS_DEBUG
883 if (ap->proc != NULL) {
884 remove_proc_entry("ap_debug", ap->proc);
885 }
886#endif /* PRISM2_NO_PROCFS_DEBUG */
887
888#ifndef PRISM2_NO_KERNEL_IEEE80211_MGMT
889 if (ap->proc != NULL) {
890 remove_proc_entry("ap", ap->proc);
891 remove_proc_entry("ap_control", ap->proc);
892 }
893 ap_control_flush_macs(&ap->mac_restrictions);
894#endif /* PRISM2_NO_KERNEL_IEEE80211_MGMT */
895
896 ap->initialized = 0;
897}
898
899
900/* caller should have mutex for AP STA list handling */
901static struct sta_info* ap_get_sta(struct ap_data *ap, u8 *sta)
902{
903 struct sta_info *s;
904
905 s = ap->sta_hash[STA_HASH(sta)];
906 while (s != NULL && memcmp(s->addr, sta, ETH_ALEN) != 0)
907 s = s->hnext;
908 return s;
909}
910
911
912#ifndef PRISM2_NO_KERNEL_IEEE80211_MGMT
913
914/* Called from timer handler and from scheduled AP queue handlers */
915static void prism2_send_mgmt(struct net_device *dev,
916 u16 type_subtype, char *body,
917 int body_len, u8 *addr, u16 tx_cb_idx)
918{
919 struct hostap_interface *iface;
920 local_info_t *local;
921 struct ieee80211_hdr *hdr;
922 u16 fc;
923 struct sk_buff *skb;
924 struct hostap_skb_tx_data *meta;
925 int hdrlen;
926
927 iface = netdev_priv(dev);
928 local = iface->local;
929 dev = local->dev; /* always use master radio device */
930 iface = netdev_priv(dev);
931
932 if (!(dev->flags & IFF_UP)) {
933 PDEBUG(DEBUG_AP, "%s: prism2_send_mgmt - device is not UP - "
934 "cannot send frame\n", dev->name);
935 return;
936 }
937
938 skb = dev_alloc_skb(sizeof(*hdr) + body_len);
939 if (skb == NULL) {
940 PDEBUG(DEBUG_AP, "%s: prism2_send_mgmt failed to allocate "
941 "skb\n", dev->name);
942 return;
943 }
944
945 fc = type_subtype;
946 hdrlen = hostap_80211_get_hdrlen(fc);
947 hdr = (struct ieee80211_hdr *) skb_put(skb, hdrlen);
948 if (body)
949 memcpy(skb_put(skb, body_len), body, body_len);
950
951 memset(hdr, 0, hdrlen);
952
953 /* FIX: ctrl::ack sending used special HFA384X_TX_CTRL_802_11
954 * tx_control instead of using local->tx_control */
955
956
957 memcpy(hdr->addr1, addr, ETH_ALEN); /* DA / RA */
958 if (WLAN_FC_GET_TYPE(fc) == IEEE80211_FTYPE_DATA) {
959 fc |= IEEE80211_FCTL_FROMDS;
960 memcpy(hdr->addr2, dev->dev_addr, ETH_ALEN); /* BSSID */
961 memcpy(hdr->addr3, dev->dev_addr, ETH_ALEN); /* SA */
962 } else if (WLAN_FC_GET_TYPE(fc) == IEEE80211_FTYPE_CTL) {
963 /* control:ACK does not have addr2 or addr3 */
964 memset(hdr->addr2, 0, ETH_ALEN);
965 memset(hdr->addr3, 0, ETH_ALEN);
966 } else {
967 memcpy(hdr->addr2, dev->dev_addr, ETH_ALEN); /* SA */
968 memcpy(hdr->addr3, dev->dev_addr, ETH_ALEN); /* BSSID */
969 }
970
971 hdr->frame_ctl = cpu_to_le16(fc);
972
973 meta = (struct hostap_skb_tx_data *) skb->cb;
974 memset(meta, 0, sizeof(*meta));
975 meta->magic = HOSTAP_SKB_TX_DATA_MAGIC;
976 meta->iface = iface;
977 meta->tx_cb_idx = tx_cb_idx;
978
979 skb->dev = dev;
980 skb->mac.raw = skb->nh.raw = skb->data;
981 dev_queue_xmit(skb);
982}
983#endif /* PRISM2_NO_KERNEL_IEEE80211_MGMT */
984
985
986static int prism2_sta_proc_read(char *page, char **start, off_t off,
987 int count, int *eof, void *data)
988{
989 char *p = page;
990 struct sta_info *sta = (struct sta_info *) data;
991 int i;
992
993 /* FIX: possible race condition.. the STA data could have just expired,
994 * but proc entry was still here so that the read could have started;
995 * some locking should be done here.. */
996
997 if (off != 0) {
998 *eof = 1;
999 return 0;
1000 }
1001
1002 p += sprintf(p, "%s=" MACSTR "\nusers=%d\naid=%d\n"
1003 "flags=0x%04x%s%s%s%s%s%s%s\n"
1004 "capability=0x%02x\nlisten_interval=%d\nsupported_rates=",
1005 sta->ap ? "AP" : "STA",
1006 MAC2STR(sta->addr), atomic_read(&sta->users), sta->aid,
1007 sta->flags,
1008 sta->flags & WLAN_STA_AUTH ? " AUTH" : "",
1009 sta->flags & WLAN_STA_ASSOC ? " ASSOC" : "",
1010 sta->flags & WLAN_STA_PS ? " PS" : "",
1011 sta->flags & WLAN_STA_TIM ? " TIM" : "",
1012 sta->flags & WLAN_STA_PERM ? " PERM" : "",
1013 sta->flags & WLAN_STA_AUTHORIZED ? " AUTHORIZED" : "",
1014 sta->flags & WLAN_STA_PENDING_POLL ? " POLL" : "",
1015 sta->capability, sta->listen_interval);
1016 /* supported_rates: 500 kbit/s units with msb ignored */
1017 for (i = 0; i < sizeof(sta->supported_rates); i++)
1018 if (sta->supported_rates[i] != 0)
1019 p += sprintf(p, "%d%sMbps ",
1020 (sta->supported_rates[i] & 0x7f) / 2,
1021 sta->supported_rates[i] & 1 ? ".5" : "");
1022 p += sprintf(p, "\njiffies=%lu\nlast_auth=%lu\nlast_assoc=%lu\n"
1023 "last_rx=%lu\nlast_tx=%lu\nrx_packets=%lu\n"
1024 "tx_packets=%lu\n"
1025 "rx_bytes=%lu\ntx_bytes=%lu\nbuffer_count=%d\n"
1026 "last_rx: silence=%d dBm signal=%d dBm rate=%d%s Mbps\n"
1027 "tx_rate=%d\ntx[1M]=%d\ntx[2M]=%d\ntx[5.5M]=%d\n"
1028 "tx[11M]=%d\n"
1029 "rx[1M]=%d\nrx[2M]=%d\nrx[5.5M]=%d\nrx[11M]=%d\n",
1030 jiffies, sta->last_auth, sta->last_assoc, sta->last_rx,
1031 sta->last_tx,
1032 sta->rx_packets, sta->tx_packets, sta->rx_bytes,
1033 sta->tx_bytes, skb_queue_len(&sta->tx_buf),
1034 sta->last_rx_silence,
1035 sta->last_rx_signal, sta->last_rx_rate / 10,
1036 sta->last_rx_rate % 10 ? ".5" : "",
1037 sta->tx_rate, sta->tx_count[0], sta->tx_count[1],
1038 sta->tx_count[2], sta->tx_count[3], sta->rx_count[0],
1039 sta->rx_count[1], sta->rx_count[2], sta->rx_count[3]);
1040 if (sta->crypt && sta->crypt->ops && sta->crypt->ops->print_stats)
1041 p = sta->crypt->ops->print_stats(p, sta->crypt->priv);
1042#ifndef PRISM2_NO_KERNEL_IEEE80211_MGMT
1043 if (sta->ap) {
1044 if (sta->u.ap.channel >= 0)
1045 p += sprintf(p, "channel=%d\n", sta->u.ap.channel);
1046 p += sprintf(p, "ssid=");
1047 for (i = 0; i < sta->u.ap.ssid_len; i++)
1048 p += sprintf(p, ((sta->u.ap.ssid[i] >= 32 &&
1049 sta->u.ap.ssid[i] < 127) ?
1050 "%c" : "<%02x>"),
1051 sta->u.ap.ssid[i]);
1052 p += sprintf(p, "\n");
1053 }
1054#endif /* PRISM2_NO_KERNEL_IEEE80211_MGMT */
1055
1056 return (p - page);
1057}
1058
1059
1060static void handle_add_proc_queue(void *data)
1061{
1062 struct ap_data *ap = (struct ap_data *) data;
1063 struct sta_info *sta;
1064 char name[20];
1065 struct add_sta_proc_data *entry, *prev;
1066
1067 entry = ap->add_sta_proc_entries;
1068 ap->add_sta_proc_entries = NULL;
1069
1070 while (entry) {
1071 spin_lock_bh(&ap->sta_table_lock);
1072 sta = ap_get_sta(ap, entry->addr);
1073 if (sta)
1074 atomic_inc(&sta->users);
1075 spin_unlock_bh(&ap->sta_table_lock);
1076
1077 if (sta) {
1078 sprintf(name, MACSTR, MAC2STR(sta->addr));
1079 sta->proc = create_proc_read_entry(
1080 name, 0, ap->proc,
1081 prism2_sta_proc_read, sta);
1082
1083 atomic_dec(&sta->users);
1084 }
1085
1086 prev = entry;
1087 entry = entry->next;
1088 kfree(prev);
1089 }
1090}
1091
1092
1093static struct sta_info * ap_add_sta(struct ap_data *ap, u8 *addr)
1094{
1095 struct sta_info *sta;
1096
1097 sta = (struct sta_info *)
1098 kmalloc(sizeof(struct sta_info), GFP_ATOMIC);
1099 if (sta == NULL) {
1100 PDEBUG(DEBUG_AP, "AP: kmalloc failed\n");
1101 return NULL;
1102 }
1103
1104 /* initialize STA info data */
1105 memset(sta, 0, sizeof(struct sta_info));
1106 sta->local = ap->local;
1107 skb_queue_head_init(&sta->tx_buf);
1108 memcpy(sta->addr, addr, ETH_ALEN);
1109
1110 atomic_inc(&sta->users);
1111 spin_lock_bh(&ap->sta_table_lock);
1112 list_add(&sta->list, &ap->sta_list);
1113 ap->num_sta++;
1114 ap_sta_hash_add(ap, sta);
1115 spin_unlock_bh(&ap->sta_table_lock);
1116
1117 if (ap->proc) {
1118 struct add_sta_proc_data *entry;
1119 /* schedule a non-interrupt context process to add a procfs
1120 * entry for the STA since procfs code use GFP_KERNEL */
1121 entry = kmalloc(sizeof(*entry), GFP_ATOMIC);
1122 if (entry) {
1123 memcpy(entry->addr, sta->addr, ETH_ALEN);
1124 entry->next = ap->add_sta_proc_entries;
1125 ap->add_sta_proc_entries = entry;
1126 schedule_work(&ap->add_sta_proc_queue);
1127 } else
1128 printk(KERN_DEBUG "Failed to add STA proc data\n");
1129 }
1130
1131#ifndef PRISM2_NO_KERNEL_IEEE80211_MGMT
1132 init_timer(&sta->timer);
1133 sta->timer.expires = jiffies + ap->max_inactivity;
1134 sta->timer.data = (unsigned long) sta;
1135 sta->timer.function = ap_handle_timer;
1136 if (!ap->local->hostapd)
1137 add_timer(&sta->timer);
1138#endif /* PRISM2_NO_KERNEL_IEEE80211_MGMT */
1139
1140 return sta;
1141}
1142
1143
1144static int ap_tx_rate_ok(int rateidx, struct sta_info *sta,
1145 local_info_t *local)
1146{
1147 if (rateidx > sta->tx_max_rate ||
1148 !(sta->tx_supp_rates & (1 << rateidx)))
1149 return 0;
1150
1151 if (local->tx_rate_control != 0 &&
1152 !(local->tx_rate_control & (1 << rateidx)))
1153 return 0;
1154
1155 return 1;
1156}
1157
1158
1159static void prism2_check_tx_rates(struct sta_info *sta)
1160{
1161 int i;
1162
1163 sta->tx_supp_rates = 0;
1164 for (i = 0; i < sizeof(sta->supported_rates); i++) {
1165 if ((sta->supported_rates[i] & 0x7f) == 2)
1166 sta->tx_supp_rates |= WLAN_RATE_1M;
1167 if ((sta->supported_rates[i] & 0x7f) == 4)
1168 sta->tx_supp_rates |= WLAN_RATE_2M;
1169 if ((sta->supported_rates[i] & 0x7f) == 11)
1170 sta->tx_supp_rates |= WLAN_RATE_5M5;
1171 if ((sta->supported_rates[i] & 0x7f) == 22)
1172 sta->tx_supp_rates |= WLAN_RATE_11M;
1173 }
1174 sta->tx_max_rate = sta->tx_rate = sta->tx_rate_idx = 0;
1175 if (sta->tx_supp_rates & WLAN_RATE_1M) {
1176 sta->tx_max_rate = 0;
1177 if (ap_tx_rate_ok(0, sta, sta->local)) {
1178 sta->tx_rate = 10;
1179 sta->tx_rate_idx = 0;
1180 }
1181 }
1182 if (sta->tx_supp_rates & WLAN_RATE_2M) {
1183 sta->tx_max_rate = 1;
1184 if (ap_tx_rate_ok(1, sta, sta->local)) {
1185 sta->tx_rate = 20;
1186 sta->tx_rate_idx = 1;
1187 }
1188 }
1189 if (sta->tx_supp_rates & WLAN_RATE_5M5) {
1190 sta->tx_max_rate = 2;
1191 if (ap_tx_rate_ok(2, sta, sta->local)) {
1192 sta->tx_rate = 55;
1193 sta->tx_rate_idx = 2;
1194 }
1195 }
1196 if (sta->tx_supp_rates & WLAN_RATE_11M) {
1197 sta->tx_max_rate = 3;
1198 if (ap_tx_rate_ok(3, sta, sta->local)) {
1199 sta->tx_rate = 110;
1200 sta->tx_rate_idx = 3;
1201 }
1202 }
1203}
1204
1205
1206#ifndef PRISM2_NO_KERNEL_IEEE80211_MGMT
1207
1208static void ap_crypt_init(struct ap_data *ap)
1209{
1210 ap->crypt = ieee80211_get_crypto_ops("WEP");
1211
1212 if (ap->crypt) {
1213 if (ap->crypt->init) {
1214 ap->crypt_priv = ap->crypt->init(0);
1215 if (ap->crypt_priv == NULL)
1216 ap->crypt = NULL;
1217 else {
1218 u8 key[WEP_KEY_LEN];
1219 get_random_bytes(key, WEP_KEY_LEN);
1220 ap->crypt->set_key(key, WEP_KEY_LEN, NULL,
1221 ap->crypt_priv);
1222 }
1223 }
1224 }
1225
1226 if (ap->crypt == NULL) {
1227 printk(KERN_WARNING "AP could not initialize WEP: load module "
1228 "ieee80211_crypt_wep.ko\n");
1229 }
1230}
1231
1232
1233/* Generate challenge data for shared key authentication. IEEE 802.11 specifies
1234 * that WEP algorithm is used for generating challange. This should be unique,
1235 * but otherwise there is not really need for randomness etc. Initialize WEP
1236 * with pseudo random key and then use increasing IV to get unique challenge
1237 * streams.
1238 *
1239 * Called only as a scheduled task for pending AP frames.
1240 */
1241static char * ap_auth_make_challenge(struct ap_data *ap)
1242{
1243 char *tmpbuf;
1244 struct sk_buff *skb;
1245
1246 if (ap->crypt == NULL) {
1247 ap_crypt_init(ap);
1248 if (ap->crypt == NULL)
1249 return NULL;
1250 }
1251
1252 tmpbuf = (char *) kmalloc(WLAN_AUTH_CHALLENGE_LEN, GFP_ATOMIC);
1253 if (tmpbuf == NULL) {
1254 PDEBUG(DEBUG_AP, "AP: kmalloc failed for challenge\n");
1255 return NULL;
1256 }
1257
1258 skb = dev_alloc_skb(WLAN_AUTH_CHALLENGE_LEN +
1259 ap->crypt->extra_prefix_len +
1260 ap->crypt->extra_postfix_len);
1261 if (skb == NULL) {
1262 kfree(tmpbuf);
1263 return NULL;
1264 }
1265
1266 skb_reserve(skb, ap->crypt->extra_prefix_len);
1267 memset(skb_put(skb, WLAN_AUTH_CHALLENGE_LEN), 0,
1268 WLAN_AUTH_CHALLENGE_LEN);
1269 if (ap->crypt->encrypt_mpdu(skb, 0, ap->crypt_priv)) {
1270 dev_kfree_skb(skb);
1271 kfree(tmpbuf);
1272 return NULL;
1273 }
1274
1275 memcpy(tmpbuf, skb->data + ap->crypt->extra_prefix_len,
1276 WLAN_AUTH_CHALLENGE_LEN);
1277 dev_kfree_skb(skb);
1278
1279 return tmpbuf;
1280}
1281
1282
1283/* Called only as a scheduled task for pending AP frames. */
1284static void handle_authen(local_info_t *local, struct sk_buff *skb,
1285 struct hostap_80211_rx_status *rx_stats)
1286{
1287 struct net_device *dev = local->dev;
1288 struct ieee80211_hdr *hdr = (struct ieee80211_hdr *) skb->data;
1289 size_t hdrlen;
1290 struct ap_data *ap = local->ap;
1291 char body[8 + WLAN_AUTH_CHALLENGE_LEN], *challenge = NULL;
1292 int len, olen;
1293 u16 auth_alg, auth_transaction, status_code, *pos;
1294 u16 resp = WLAN_STATUS_SUCCESS, fc;
1295 struct sta_info *sta = NULL;
1296 struct ieee80211_crypt_data *crypt;
1297 char *txt = "";
1298
1299 len = skb->len - IEEE80211_MGMT_HDR_LEN;
1300
1301 fc = le16_to_cpu(hdr->frame_ctl);
1302 hdrlen = hostap_80211_get_hdrlen(fc);
1303
1304 if (len < 6) {
1305 PDEBUG(DEBUG_AP, "%s: handle_authen - too short payload "
1306 "(len=%d) from " MACSTR "\n", dev->name, len,
1307 MAC2STR(hdr->addr2));
1308 return;
1309 }
1310
1311 spin_lock_bh(&local->ap->sta_table_lock);
1312 sta = ap_get_sta(local->ap, hdr->addr2);
1313 if (sta)
1314 atomic_inc(&sta->users);
1315 spin_unlock_bh(&local->ap->sta_table_lock);
1316
1317 if (sta && sta->crypt)
1318 crypt = sta->crypt;
1319 else {
1320 int idx = 0;
1321 if (skb->len >= hdrlen + 3)
1322 idx = skb->data[hdrlen + 3] >> 6;
1323 crypt = local->crypt[idx];
1324 }
1325
1326 pos = (u16 *) (skb->data + IEEE80211_MGMT_HDR_LEN);
1327 auth_alg = __le16_to_cpu(*pos);
1328 pos++;
1329 auth_transaction = __le16_to_cpu(*pos);
1330 pos++;
1331 status_code = __le16_to_cpu(*pos);
1332 pos++;
1333
1334 if (memcmp(dev->dev_addr, hdr->addr2, ETH_ALEN) == 0 ||
1335 ap_control_mac_deny(&ap->mac_restrictions, hdr->addr2)) {
1336 txt = "authentication denied";
1337 resp = WLAN_STATUS_UNSPECIFIED_FAILURE;
1338 goto fail;
1339 }
1340
1341 if (((local->auth_algs & PRISM2_AUTH_OPEN) &&
1342 auth_alg == WLAN_AUTH_OPEN) ||
1343 ((local->auth_algs & PRISM2_AUTH_SHARED_KEY) &&
1344 crypt && auth_alg == WLAN_AUTH_SHARED_KEY)) {
1345 } else {
1346 txt = "unsupported algorithm";
1347 resp = WLAN_STATUS_NOT_SUPPORTED_AUTH_ALG;
1348 goto fail;
1349 }
1350
1351 if (len >= 8) {
1352 u8 *u = (u8 *) pos;
1353 if (*u == WLAN_EID_CHALLENGE) {
1354 if (*(u + 1) != WLAN_AUTH_CHALLENGE_LEN) {
1355 txt = "invalid challenge len";
1356 resp = WLAN_STATUS_CHALLENGE_FAIL;
1357 goto fail;
1358 }
1359 if (len - 8 < WLAN_AUTH_CHALLENGE_LEN) {
1360 txt = "challenge underflow";
1361 resp = WLAN_STATUS_CHALLENGE_FAIL;
1362 goto fail;
1363 }
1364 challenge = (char *) (u + 2);
1365 }
1366 }
1367
1368 if (sta && sta->ap) {
1369 if (time_after(jiffies, sta->u.ap.last_beacon +
1370 (10 * sta->listen_interval * HZ) / 1024)) {
1371 PDEBUG(DEBUG_AP, "%s: no beacons received for a while,"
1372 " assuming AP " MACSTR " is now STA\n",
1373 dev->name, MAC2STR(sta->addr));
1374 sta->ap = 0;
1375 sta->flags = 0;
1376 sta->u.sta.challenge = NULL;
1377 } else {
1378 txt = "AP trying to authenticate?";
1379 resp = WLAN_STATUS_UNSPECIFIED_FAILURE;
1380 goto fail;
1381 }
1382 }
1383
1384 if ((auth_alg == WLAN_AUTH_OPEN && auth_transaction == 1) ||
1385 (auth_alg == WLAN_AUTH_SHARED_KEY &&
1386 (auth_transaction == 1 ||
1387 (auth_transaction == 3 && sta != NULL &&
1388 sta->u.sta.challenge != NULL)))) {
1389 } else {
1390 txt = "unknown authentication transaction number";
1391 resp = WLAN_STATUS_UNKNOWN_AUTH_TRANSACTION;
1392 goto fail;
1393 }
1394
1395 if (sta == NULL) {
1396 txt = "new STA";
1397
1398 if (local->ap->num_sta >= MAX_STA_COUNT) {
1399 /* FIX: might try to remove some old STAs first? */
1400 txt = "no more room for new STAs";
1401 resp = WLAN_STATUS_UNSPECIFIED_FAILURE;
1402 goto fail;
1403 }
1404
1405 sta = ap_add_sta(local->ap, hdr->addr2);
1406 if (sta == NULL) {
1407 txt = "ap_add_sta failed";
1408 resp = WLAN_STATUS_UNSPECIFIED_FAILURE;
1409 goto fail;
1410 }
1411 }
1412
1413 switch (auth_alg) {
1414 case WLAN_AUTH_OPEN:
1415 txt = "authOK";
1416 /* IEEE 802.11 standard is not completely clear about
1417 * whether STA is considered authenticated after
1418 * authentication OK frame has been send or after it
1419 * has been ACKed. In order to reduce interoperability
1420 * issues, mark the STA authenticated before ACK. */
1421 sta->flags |= WLAN_STA_AUTH;
1422 break;
1423
1424 case WLAN_AUTH_SHARED_KEY:
1425 if (auth_transaction == 1) {
1426 if (sta->u.sta.challenge == NULL) {
1427 sta->u.sta.challenge =
1428 ap_auth_make_challenge(local->ap);
1429 if (sta->u.sta.challenge == NULL) {
1430 resp = WLAN_STATUS_UNSPECIFIED_FAILURE;
1431 goto fail;
1432 }
1433 }
1434 } else {
1435 if (sta->u.sta.challenge == NULL ||
1436 challenge == NULL ||
1437 memcmp(sta->u.sta.challenge, challenge,
1438 WLAN_AUTH_CHALLENGE_LEN) != 0 ||
1439 !(fc & IEEE80211_FCTL_PROTECTED)) {
1440 txt = "challenge response incorrect";
1441 resp = WLAN_STATUS_CHALLENGE_FAIL;
1442 goto fail;
1443 }
1444
1445 txt = "challenge OK - authOK";
1446 /* IEEE 802.11 standard is not completely clear about
1447 * whether STA is considered authenticated after
1448 * authentication OK frame has been send or after it
1449 * has been ACKed. In order to reduce interoperability
1450 * issues, mark the STA authenticated before ACK. */
1451 sta->flags |= WLAN_STA_AUTH;
1452 kfree(sta->u.sta.challenge);
1453 sta->u.sta.challenge = NULL;
1454 }
1455 break;
1456 }
1457
1458 fail:
1459 pos = (u16 *) body;
1460 *pos = cpu_to_le16(auth_alg);
1461 pos++;
1462 *pos = cpu_to_le16(auth_transaction + 1);
1463 pos++;
1464 *pos = cpu_to_le16(resp); /* status_code */
1465 pos++;
1466 olen = 6;
1467
1468 if (resp == WLAN_STATUS_SUCCESS && sta != NULL &&
1469 sta->u.sta.challenge != NULL &&
1470 auth_alg == WLAN_AUTH_SHARED_KEY && auth_transaction == 1) {
1471 u8 *tmp = (u8 *) pos;
1472 *tmp++ = WLAN_EID_CHALLENGE;
1473 *tmp++ = WLAN_AUTH_CHALLENGE_LEN;
1474 pos++;
1475 memcpy(pos, sta->u.sta.challenge, WLAN_AUTH_CHALLENGE_LEN);
1476 olen += 2 + WLAN_AUTH_CHALLENGE_LEN;
1477 }
1478
1479 prism2_send_mgmt(dev, IEEE80211_FTYPE_MGMT | IEEE80211_STYPE_AUTH,
1480 body, olen, hdr->addr2, ap->tx_callback_auth);
1481
1482 if (sta) {
1483 sta->last_rx = jiffies;
1484 atomic_dec(&sta->users);
1485 }
1486
1487 if (resp) {
1488 PDEBUG(DEBUG_AP, "%s: " MACSTR " auth (alg=%d trans#=%d "
1489 "stat=%d len=%d fc=%04x) ==> %d (%s)\n",
1490 dev->name, MAC2STR(hdr->addr2), auth_alg,
1491 auth_transaction, status_code, len, fc, resp, txt);
1492 }
1493}
1494
1495
1496/* Called only as a scheduled task for pending AP frames. */
1497static void handle_assoc(local_info_t *local, struct sk_buff *skb,
1498 struct hostap_80211_rx_status *rx_stats, int reassoc)
1499{
1500 struct net_device *dev = local->dev;
1501 struct ieee80211_hdr *hdr = (struct ieee80211_hdr *) skb->data;
1502 char body[12], *p, *lpos;
1503 int len, left;
1504 u16 *pos;
1505 u16 resp = WLAN_STATUS_SUCCESS;
1506 struct sta_info *sta = NULL;
1507 int send_deauth = 0;
1508 char *txt = "";
1509 u8 prev_ap[ETH_ALEN];
1510
1511 left = len = skb->len - IEEE80211_MGMT_HDR_LEN;
1512
1513 if (len < (reassoc ? 10 : 4)) {
1514 PDEBUG(DEBUG_AP, "%s: handle_assoc - too short payload "
1515 "(len=%d, reassoc=%d) from " MACSTR "\n",
1516 dev->name, len, reassoc, MAC2STR(hdr->addr2));
1517 return;
1518 }
1519
1520 spin_lock_bh(&local->ap->sta_table_lock);
1521 sta = ap_get_sta(local->ap, hdr->addr2);
1522 if (sta == NULL || (sta->flags & WLAN_STA_AUTH) == 0) {
1523 spin_unlock_bh(&local->ap->sta_table_lock);
1524 txt = "trying to associate before authentication";
1525 send_deauth = 1;
1526 resp = WLAN_STATUS_UNSPECIFIED_FAILURE;
1527 sta = NULL; /* do not decrement sta->users */
1528 goto fail;
1529 }
1530 atomic_inc(&sta->users);
1531 spin_unlock_bh(&local->ap->sta_table_lock);
1532
1533 pos = (u16 *) (skb->data + IEEE80211_MGMT_HDR_LEN);
1534 sta->capability = __le16_to_cpu(*pos);
1535 pos++; left -= 2;
1536 sta->listen_interval = __le16_to_cpu(*pos);
1537 pos++; left -= 2;
1538
1539 if (reassoc) {
1540 memcpy(prev_ap, pos, ETH_ALEN);
1541 pos++; pos++; pos++; left -= 6;
1542 } else
1543 memset(prev_ap, 0, ETH_ALEN);
1544
1545 if (left >= 2) {
1546 unsigned int ileft;
1547 unsigned char *u = (unsigned char *) pos;
1548
1549 if (*u == WLAN_EID_SSID) {
1550 u++; left--;
1551 ileft = *u;
1552 u++; left--;
1553
1554 if (ileft > left || ileft > MAX_SSID_LEN) {
1555 txt = "SSID overflow";
1556 resp = WLAN_STATUS_UNSPECIFIED_FAILURE;
1557 goto fail;
1558 }
1559
1560 if (ileft != strlen(local->essid) ||
1561 memcmp(local->essid, u, ileft) != 0) {
1562 txt = "not our SSID";
1563 resp = WLAN_STATUS_ASSOC_DENIED_UNSPEC;
1564 goto fail;
1565 }
1566
1567 u += ileft;
1568 left -= ileft;
1569 }
1570
1571 if (left >= 2 && *u == WLAN_EID_SUPP_RATES) {
1572 u++; left--;
1573 ileft = *u;
1574 u++; left--;
1575
1576 if (ileft > left || ileft == 0 ||
1577 ileft > WLAN_SUPP_RATES_MAX) {
1578 txt = "SUPP_RATES len error";
1579 resp = WLAN_STATUS_UNSPECIFIED_FAILURE;
1580 goto fail;
1581 }
1582
1583 memset(sta->supported_rates, 0,
1584 sizeof(sta->supported_rates));
1585 memcpy(sta->supported_rates, u, ileft);
1586 prism2_check_tx_rates(sta);
1587
1588 u += ileft;
1589 left -= ileft;
1590 }
1591
1592 if (left > 0) {
1593 PDEBUG(DEBUG_AP, "%s: assoc from " MACSTR " with extra"
1594 " data (%d bytes) [",
1595 dev->name, MAC2STR(hdr->addr2), left);
1596 while (left > 0) {
1597 PDEBUG2(DEBUG_AP, "<%02x>", *u);
1598 u++; left--;
1599 }
1600 PDEBUG2(DEBUG_AP, "]\n");
1601 }
1602 } else {
1603 txt = "frame underflow";
1604 resp = WLAN_STATUS_UNSPECIFIED_FAILURE;
1605 goto fail;
1606 }
1607
1608 /* get a unique AID */
1609 if (sta->aid > 0)
1610 txt = "OK, old AID";
1611 else {
1612 spin_lock_bh(&local->ap->sta_table_lock);
1613 for (sta->aid = 1; sta->aid <= MAX_AID_TABLE_SIZE; sta->aid++)
1614 if (local->ap->sta_aid[sta->aid - 1] == NULL)
1615 break;
1616 if (sta->aid > MAX_AID_TABLE_SIZE) {
1617 sta->aid = 0;
1618 spin_unlock_bh(&local->ap->sta_table_lock);
1619 resp = WLAN_STATUS_AP_UNABLE_TO_HANDLE_NEW_STA;
1620 txt = "no room for more AIDs";
1621 } else {
1622 local->ap->sta_aid[sta->aid - 1] = sta;
1623 spin_unlock_bh(&local->ap->sta_table_lock);
1624 txt = "OK, new AID";
1625 }
1626 }
1627
1628 fail:
1629 pos = (u16 *) body;
1630
1631 if (send_deauth) {
1632 *pos = __constant_cpu_to_le16(
1633 WLAN_REASON_STA_REQ_ASSOC_WITHOUT_AUTH);
1634 pos++;
1635 } else {
1636 /* FIX: CF-Pollable and CF-PollReq should be set to match the
1637 * values in beacons/probe responses */
1638 /* FIX: how about privacy and WEP? */
1639 /* capability */
1640 *pos = __constant_cpu_to_le16(WLAN_CAPABILITY_ESS);
1641 pos++;
1642
1643 /* status_code */
1644 *pos = __cpu_to_le16(resp);
1645 pos++;
1646
1647 *pos = __cpu_to_le16((sta && sta->aid > 0 ? sta->aid : 0) |
1648 BIT(14) | BIT(15)); /* AID */
1649 pos++;
1650
1651 /* Supported rates (Information element) */
1652 p = (char *) pos;
1653 *p++ = WLAN_EID_SUPP_RATES;
1654 lpos = p;
1655 *p++ = 0; /* len */
1656 if (local->tx_rate_control & WLAN_RATE_1M) {
1657 *p++ = local->basic_rates & WLAN_RATE_1M ? 0x82 : 0x02;
1658 (*lpos)++;
1659 }
1660 if (local->tx_rate_control & WLAN_RATE_2M) {
1661 *p++ = local->basic_rates & WLAN_RATE_2M ? 0x84 : 0x04;
1662 (*lpos)++;
1663 }
1664 if (local->tx_rate_control & WLAN_RATE_5M5) {
1665 *p++ = local->basic_rates & WLAN_RATE_5M5 ?
1666 0x8b : 0x0b;
1667 (*lpos)++;
1668 }
1669 if (local->tx_rate_control & WLAN_RATE_11M) {
1670 *p++ = local->basic_rates & WLAN_RATE_11M ?
1671 0x96 : 0x16;
1672 (*lpos)++;
1673 }
1674 pos = (u16 *) p;
1675 }
1676
1677 prism2_send_mgmt(dev, IEEE80211_FTYPE_MGMT |
1678 (send_deauth ? IEEE80211_STYPE_DEAUTH :
1679 (reassoc ? IEEE80211_STYPE_REASSOC_RESP :
1680 IEEE80211_STYPE_ASSOC_RESP)),
1681 body, (u8 *) pos - (u8 *) body,
1682 hdr->addr2,
1683 send_deauth ? 0 : local->ap->tx_callback_assoc);
1684
1685 if (sta) {
1686 if (resp == WLAN_STATUS_SUCCESS) {
1687 sta->last_rx = jiffies;
1688 /* STA will be marked associated from TX callback, if
1689 * AssocResp is ACKed */
1690 }
1691 atomic_dec(&sta->users);
1692 }
1693
1694#if 0
1695 PDEBUG(DEBUG_AP, "%s: " MACSTR " %sassoc (len=%d prev_ap=" MACSTR
1696 ") => %d(%d) (%s)\n",
1697 dev->name, MAC2STR(hdr->addr2), reassoc ? "re" : "", len,
1698 MAC2STR(prev_ap), resp, send_deauth, txt);
1699#endif
1700}
1701
1702
1703/* Called only as a scheduled task for pending AP frames. */
1704static void handle_deauth(local_info_t *local, struct sk_buff *skb,
1705 struct hostap_80211_rx_status *rx_stats)
1706{
1707 struct net_device *dev = local->dev;
1708 struct ieee80211_hdr *hdr = (struct ieee80211_hdr *) skb->data;
1709 char *body = (char *) (skb->data + IEEE80211_MGMT_HDR_LEN);
1710 int len;
1711 u16 reason_code, *pos;
1712 struct sta_info *sta = NULL;
1713
1714 len = skb->len - IEEE80211_MGMT_HDR_LEN;
1715
1716 if (len < 2) {
1717 printk("handle_deauth - too short payload (len=%d)\n", len);
1718 return;
1719 }
1720
1721 pos = (u16 *) body;
1722 reason_code = __le16_to_cpu(*pos);
1723
1724 PDEBUG(DEBUG_AP, "%s: deauthentication: " MACSTR " len=%d, "
1725 "reason_code=%d\n", dev->name, MAC2STR(hdr->addr2), len,
1726 reason_code);
1727
1728 spin_lock_bh(&local->ap->sta_table_lock);
1729 sta = ap_get_sta(local->ap, hdr->addr2);
1730 if (sta != NULL) {
1731 if ((sta->flags & WLAN_STA_ASSOC) && !sta->ap)
1732 hostap_event_expired_sta(local->dev, sta);
1733 sta->flags &= ~(WLAN_STA_AUTH | WLAN_STA_ASSOC);
1734 }
1735 spin_unlock_bh(&local->ap->sta_table_lock);
1736 if (sta == NULL) {
1737 printk("%s: deauthentication from " MACSTR ", "
1738 "reason_code=%d, but STA not authenticated\n", dev->name,
1739 MAC2STR(hdr->addr2), reason_code);
1740 }
1741}
1742
1743
1744/* Called only as a scheduled task for pending AP frames. */
1745static void handle_disassoc(local_info_t *local, struct sk_buff *skb,
1746 struct hostap_80211_rx_status *rx_stats)
1747{
1748 struct net_device *dev = local->dev;
1749 struct ieee80211_hdr *hdr = (struct ieee80211_hdr *) skb->data;
1750 char *body = skb->data + IEEE80211_MGMT_HDR_LEN;
1751 int len;
1752 u16 reason_code, *pos;
1753 struct sta_info *sta = NULL;
1754
1755 len = skb->len - IEEE80211_MGMT_HDR_LEN;
1756
1757 if (len < 2) {
1758 printk("handle_disassoc - too short payload (len=%d)\n", len);
1759 return;
1760 }
1761
1762 pos = (u16 *) body;
1763 reason_code = __le16_to_cpu(*pos);
1764
1765 PDEBUG(DEBUG_AP, "%s: disassociation: " MACSTR " len=%d, "
1766 "reason_code=%d\n", dev->name, MAC2STR(hdr->addr2), len,
1767 reason_code);
1768
1769 spin_lock_bh(&local->ap->sta_table_lock);
1770 sta = ap_get_sta(local->ap, hdr->addr2);
1771 if (sta != NULL) {
1772 if ((sta->flags & WLAN_STA_ASSOC) && !sta->ap)
1773 hostap_event_expired_sta(local->dev, sta);
1774 sta->flags &= ~WLAN_STA_ASSOC;
1775 }
1776 spin_unlock_bh(&local->ap->sta_table_lock);
1777 if (sta == NULL) {
1778 printk("%s: disassociation from " MACSTR ", "
1779 "reason_code=%d, but STA not authenticated\n",
1780 dev->name, MAC2STR(hdr->addr2), reason_code);
1781 }
1782}
1783
1784
1785/* Called only as a scheduled task for pending AP frames. */
1786static void ap_handle_data_nullfunc(local_info_t *local,
1787 struct ieee80211_hdr *hdr)
1788{
1789 struct net_device *dev = local->dev;
1790
1791 /* some STA f/w's seem to require control::ACK frame for
1792 * data::nullfunc, but at least Prism2 station f/w version 0.8.0 does
1793 * not send this..
1794 * send control::ACK for the data::nullfunc */
1795
1796 printk(KERN_DEBUG "Sending control::ACK for data::nullfunc\n");
1797 prism2_send_mgmt(dev, IEEE80211_FTYPE_CTL | IEEE80211_STYPE_ACK,
1798 NULL, 0, hdr->addr2, 0);
1799}
1800
1801
1802/* Called only as a scheduled task for pending AP frames. */
1803static void ap_handle_dropped_data(local_info_t *local,
1804 struct ieee80211_hdr *hdr)
1805{
1806 struct net_device *dev = local->dev;
1807 struct sta_info *sta;
1808 u16 reason;
1809
1810 spin_lock_bh(&local->ap->sta_table_lock);
1811 sta = ap_get_sta(local->ap, hdr->addr2);
1812 if (sta)
1813 atomic_inc(&sta->users);
1814 spin_unlock_bh(&local->ap->sta_table_lock);
1815
1816 if (sta != NULL && (sta->flags & WLAN_STA_ASSOC)) {
1817 PDEBUG(DEBUG_AP, "ap_handle_dropped_data: STA is now okay?\n");
1818 atomic_dec(&sta->users);
1819 return;
1820 }
1821
1822 reason = __constant_cpu_to_le16(
1823 WLAN_REASON_CLASS3_FRAME_FROM_NONASSOC_STA);
1824 prism2_send_mgmt(dev, IEEE80211_FTYPE_MGMT |
1825 ((sta == NULL || !(sta->flags & WLAN_STA_ASSOC)) ?
1826 IEEE80211_STYPE_DEAUTH : IEEE80211_STYPE_DISASSOC),
1827 (char *) &reason, sizeof(reason), hdr->addr2, 0);
1828
1829 if (sta)
1830 atomic_dec(&sta->users);
1831}
1832
1833#endif /* PRISM2_NO_KERNEL_IEEE80211_MGMT */
1834
1835
1836/* Called only as a scheduled task for pending AP frames. */
1837static void pspoll_send_buffered(local_info_t *local, struct sta_info *sta,
1838 struct sk_buff *skb)
1839{
1840 struct hostap_skb_tx_data *meta;
1841
1842 if (!(sta->flags & WLAN_STA_PS)) {
1843 /* Station has moved to non-PS mode, so send all buffered
1844 * frames using normal device queue. */
1845 dev_queue_xmit(skb);
1846 return;
1847 }
1848
1849 /* add a flag for hostap_handle_sta_tx() to know that this skb should
1850 * be passed through even though STA is using PS */
1851 meta = (struct hostap_skb_tx_data *) skb->cb;
1852 meta->flags |= HOSTAP_TX_FLAGS_BUFFERED_FRAME;
1853 if (!skb_queue_empty(&sta->tx_buf)) {
1854 /* indicate to STA that more frames follow */
1855 meta->flags |= HOSTAP_TX_FLAGS_ADD_MOREDATA;
1856 }
1857 dev_queue_xmit(skb);
1858}
1859
1860
1861/* Called only as a scheduled task for pending AP frames. */
1862static void handle_pspoll(local_info_t *local,
1863 struct ieee80211_hdr *hdr,
1864 struct hostap_80211_rx_status *rx_stats)
1865{
1866 struct net_device *dev = local->dev;
1867 struct sta_info *sta;
1868 u16 aid;
1869 struct sk_buff *skb;
1870
1871 PDEBUG(DEBUG_PS2, "handle_pspoll: BSSID=" MACSTR ", TA=" MACSTR
1872 " PWRMGT=%d\n",
1873 MAC2STR(hdr->addr1), MAC2STR(hdr->addr2),
1874 !!(le16_to_cpu(hdr->frame_ctl) & IEEE80211_FCTL_PM));
1875
1876 if (memcmp(hdr->addr1, dev->dev_addr, ETH_ALEN)) {
1877 PDEBUG(DEBUG_AP, "handle_pspoll - addr1(BSSID)=" MACSTR
1878 " not own MAC\n", MAC2STR(hdr->addr1));
1879 return;
1880 }
1881
1882 aid = __le16_to_cpu(hdr->duration_id);
1883 if ((aid & (BIT(15) | BIT(14))) != (BIT(15) | BIT(14))) {
1884 PDEBUG(DEBUG_PS, " PSPOLL and AID[15:14] not set\n");
1885 return;
1886 }
1887 aid &= ~BIT(15) & ~BIT(14);
1888 if (aid == 0 || aid > MAX_AID_TABLE_SIZE) {
1889 PDEBUG(DEBUG_PS, " invalid aid=%d\n", aid);
1890 return;
1891 }
1892 PDEBUG(DEBUG_PS2, " aid=%d\n", aid);
1893
1894 spin_lock_bh(&local->ap->sta_table_lock);
1895 sta = ap_get_sta(local->ap, hdr->addr2);
1896 if (sta)
1897 atomic_inc(&sta->users);
1898 spin_unlock_bh(&local->ap->sta_table_lock);
1899
1900 if (sta == NULL) {
1901 PDEBUG(DEBUG_PS, " STA not found\n");
1902 return;
1903 }
1904 if (sta->aid != aid) {
1905 PDEBUG(DEBUG_PS, " received aid=%i does not match with "
1906 "assoc.aid=%d\n", aid, sta->aid);
1907 return;
1908 }
1909
1910 /* FIX: todo:
1911 * - add timeout for buffering (clear aid in TIM vector if buffer timed
1912 * out (expiry time must be longer than ListenInterval for
1913 * the corresponding STA; "8802-11: 11.2.1.9 AP aging function"
1914 * - what to do, if buffered, pspolled, and sent frame is not ACKed by
1915 * sta; store buffer for later use and leave TIM aid bit set? use
1916 * TX event to check whether frame was ACKed?
1917 */
1918
1919 while ((skb = skb_dequeue(&sta->tx_buf)) != NULL) {
1920 /* send buffered frame .. */
1921 PDEBUG(DEBUG_PS2, "Sending buffered frame to STA after PS POLL"
1922 " (buffer_count=%d)\n", skb_queue_len(&sta->tx_buf));
1923
1924 pspoll_send_buffered(local, sta, skb);
1925
1926 if (sta->flags & WLAN_STA_PS) {
1927 /* send only one buffered packet per PS Poll */
1928 /* FIX: should ignore further PS Polls until the
1929 * buffered packet that was just sent is acknowledged
1930 * (Tx or TxExc event) */
1931 break;
1932 }
1933 }
1934
1935 if (skb_queue_empty(&sta->tx_buf)) {
1936 /* try to clear aid from TIM */
1937 if (!(sta->flags & WLAN_STA_TIM))
1938 PDEBUG(DEBUG_PS2, "Re-unsetting TIM for aid %d\n",
1939 aid);
1940 hostap_set_tim(local, aid, 0);
1941 sta->flags &= ~WLAN_STA_TIM;
1942 }
1943
1944 atomic_dec(&sta->users);
1945}
1946
1947
1948#ifndef PRISM2_NO_KERNEL_IEEE80211_MGMT
1949
1950static void handle_wds_oper_queue(void *data)
1951{
1952 local_info_t *local = data;
1953 struct wds_oper_data *entry, *prev;
1954
1955 spin_lock_bh(&local->lock);
1956 entry = local->ap->wds_oper_entries;
1957 local->ap->wds_oper_entries = NULL;
1958 spin_unlock_bh(&local->lock);
1959
1960 while (entry) {
1961 PDEBUG(DEBUG_AP, "%s: %s automatic WDS connection "
1962 "to AP " MACSTR "\n",
1963 local->dev->name,
1964 entry->type == WDS_ADD ? "adding" : "removing",
1965 MAC2STR(entry->addr));
1966 if (entry->type == WDS_ADD)
1967 prism2_wds_add(local, entry->addr, 0);
1968 else if (entry->type == WDS_DEL)
1969 prism2_wds_del(local, entry->addr, 0, 1);
1970
1971 prev = entry;
1972 entry = entry->next;
1973 kfree(prev);
1974 }
1975}
1976
1977
1978/* Called only as a scheduled task for pending AP frames. */
1979static void handle_beacon(local_info_t *local, struct sk_buff *skb,
1980 struct hostap_80211_rx_status *rx_stats)
1981{
1982 struct ieee80211_hdr *hdr = (struct ieee80211_hdr *) skb->data;
1983 char *body = skb->data + IEEE80211_MGMT_HDR_LEN;
1984 int len, left;
1985 u16 *pos, beacon_int, capability;
1986 char *ssid = NULL;
1987 unsigned char *supp_rates = NULL;
1988 int ssid_len = 0, supp_rates_len = 0;
1989 struct sta_info *sta = NULL;
1990 int new_sta = 0, channel = -1;
1991
1992 len = skb->len - IEEE80211_MGMT_HDR_LEN;
1993
1994 if (len < 8 + 2 + 2) {
1995 printk(KERN_DEBUG "handle_beacon - too short payload "
1996 "(len=%d)\n", len);
1997 return;
1998 }
1999
2000 pos = (u16 *) body;
2001 left = len;
2002
2003 /* Timestamp (8 octets) */
2004 pos += 4; left -= 8;
2005 /* Beacon interval (2 octets) */
2006 beacon_int = __le16_to_cpu(*pos);
2007 pos++; left -= 2;
2008 /* Capability information (2 octets) */
2009 capability = __le16_to_cpu(*pos);
2010 pos++; left -= 2;
2011
2012 if (local->ap->ap_policy != AP_OTHER_AP_EVEN_IBSS &&
2013 capability & WLAN_CAPABILITY_IBSS)
2014 return;
2015
2016 if (left >= 2) {
2017 unsigned int ileft;
2018 unsigned char *u = (unsigned char *) pos;
2019
2020 if (*u == WLAN_EID_SSID) {
2021 u++; left--;
2022 ileft = *u;
2023 u++; left--;
2024
2025 if (ileft > left || ileft > MAX_SSID_LEN) {
2026 PDEBUG(DEBUG_AP, "SSID: overflow\n");
2027 return;
2028 }
2029
2030 if (local->ap->ap_policy == AP_OTHER_AP_SAME_SSID &&
2031 (ileft != strlen(local->essid) ||
2032 memcmp(local->essid, u, ileft) != 0)) {
2033 /* not our SSID */
2034 return;
2035 }
2036
2037 ssid = u;
2038 ssid_len = ileft;
2039
2040 u += ileft;
2041 left -= ileft;
2042 }
2043
2044 if (*u == WLAN_EID_SUPP_RATES) {
2045 u++; left--;
2046 ileft = *u;
2047 u++; left--;
2048
2049 if (ileft > left || ileft == 0 || ileft > 8) {
2050 PDEBUG(DEBUG_AP, " - SUPP_RATES len error\n");
2051 return;
2052 }
2053
2054 supp_rates = u;
2055 supp_rates_len = ileft;
2056
2057 u += ileft;
2058 left -= ileft;
2059 }
2060
2061 if (*u == WLAN_EID_DS_PARAMS) {
2062 u++; left--;
2063 ileft = *u;
2064 u++; left--;
2065
2066 if (ileft > left || ileft != 1) {
2067 PDEBUG(DEBUG_AP, " - DS_PARAMS len error\n");
2068 return;
2069 }
2070
2071 channel = *u;
2072
2073 u += ileft;
2074 left -= ileft;
2075 }
2076 }
2077
2078 spin_lock_bh(&local->ap->sta_table_lock);
2079 sta = ap_get_sta(local->ap, hdr->addr2);
2080 if (sta != NULL)
2081 atomic_inc(&sta->users);
2082 spin_unlock_bh(&local->ap->sta_table_lock);
2083
2084 if (sta == NULL) {
2085 /* add new AP */
2086 new_sta = 1;
2087 sta = ap_add_sta(local->ap, hdr->addr2);
2088 if (sta == NULL) {
2089 printk(KERN_INFO "prism2: kmalloc failed for AP "
2090 "data structure\n");
2091 return;
2092 }
2093 hostap_event_new_sta(local->dev, sta);
2094
2095 /* mark APs authentication and associated for pseudo ad-hoc
2096 * style communication */
2097 sta->flags = WLAN_STA_AUTH | WLAN_STA_ASSOC;
2098
2099 if (local->ap->autom_ap_wds) {
2100 hostap_wds_link_oper(local, sta->addr, WDS_ADD);
2101 }
2102 }
2103
2104 sta->ap = 1;
2105 if (ssid) {
2106 sta->u.ap.ssid_len = ssid_len;
2107 memcpy(sta->u.ap.ssid, ssid, ssid_len);
2108 sta->u.ap.ssid[ssid_len] = '\0';
2109 } else {
2110 sta->u.ap.ssid_len = 0;
2111 sta->u.ap.ssid[0] = '\0';
2112 }
2113 sta->u.ap.channel = channel;
2114 sta->rx_packets++;
2115 sta->rx_bytes += len;
2116 sta->u.ap.last_beacon = sta->last_rx = jiffies;
2117 sta->capability = capability;
2118 sta->listen_interval = beacon_int;
2119
2120 atomic_dec(&sta->users);
2121
2122 if (new_sta) {
2123 memset(sta->supported_rates, 0, sizeof(sta->supported_rates));
2124 memcpy(sta->supported_rates, supp_rates, supp_rates_len);
2125 prism2_check_tx_rates(sta);
2126 }
2127}
2128
2129#endif /* PRISM2_NO_KERNEL_IEEE80211_MGMT */
2130
2131
2132/* Called only as a tasklet. */
2133static void handle_ap_item(local_info_t *local, struct sk_buff *skb,
2134 struct hostap_80211_rx_status *rx_stats)
2135{
2136#ifndef PRISM2_NO_KERNEL_IEEE80211_MGMT
2137 struct net_device *dev = local->dev;
2138#endif /* PRISM2_NO_KERNEL_IEEE80211_MGMT */
2139 u16 fc, type, stype;
2140 struct ieee80211_hdr *hdr;
2141
2142 /* FIX: should give skb->len to handler functions and check that the
2143 * buffer is long enough */
2144 hdr = (struct ieee80211_hdr *) skb->data;
2145 fc = le16_to_cpu(hdr->frame_ctl);
2146 type = WLAN_FC_GET_TYPE(fc);
2147 stype = WLAN_FC_GET_STYPE(fc);
2148
2149#ifndef PRISM2_NO_KERNEL_IEEE80211_MGMT
2150 if (!local->hostapd && type == IEEE80211_FTYPE_DATA) {
2151 PDEBUG(DEBUG_AP, "handle_ap_item - data frame\n");
2152
2153 if (!(fc & IEEE80211_FCTL_TODS) ||
2154 (fc & IEEE80211_FCTL_FROMDS)) {
2155 if (stype == IEEE80211_STYPE_NULLFUNC) {
2156 /* no ToDS nullfunc seems to be used to check
2157 * AP association; so send reject message to
2158 * speed up re-association */
2159 ap_handle_dropped_data(local, hdr);
2160 goto done;
2161 }
2162 PDEBUG(DEBUG_AP, " not ToDS frame (fc=0x%04x)\n",
2163 fc);
2164 goto done;
2165 }
2166
2167 if (memcmp(hdr->addr1, dev->dev_addr, ETH_ALEN)) {
2168 PDEBUG(DEBUG_AP, "handle_ap_item - addr1(BSSID)="
2169 MACSTR " not own MAC\n",
2170 MAC2STR(hdr->addr1));
2171 goto done;
2172 }
2173
2174 if (local->ap->nullfunc_ack &&
2175 stype == IEEE80211_STYPE_NULLFUNC)
2176 ap_handle_data_nullfunc(local, hdr);
2177 else
2178 ap_handle_dropped_data(local, hdr);
2179 goto done;
2180 }
2181
2182 if (type == IEEE80211_FTYPE_MGMT && stype == IEEE80211_STYPE_BEACON) {
2183 handle_beacon(local, skb, rx_stats);
2184 goto done;
2185 }
2186#endif /* PRISM2_NO_KERNEL_IEEE80211_MGMT */
2187
2188 if (type == IEEE80211_FTYPE_CTL && stype == IEEE80211_STYPE_PSPOLL) {
2189 handle_pspoll(local, hdr, rx_stats);
2190 goto done;
2191 }
2192
2193 if (local->hostapd) {
2194 PDEBUG(DEBUG_AP, "Unknown frame in AP queue: type=0x%02x "
2195 "subtype=0x%02x\n", type, stype);
2196 goto done;
2197 }
2198
2199#ifndef PRISM2_NO_KERNEL_IEEE80211_MGMT
2200 if (type != IEEE80211_FTYPE_MGMT) {
2201 PDEBUG(DEBUG_AP, "handle_ap_item - not a management frame?\n");
2202 goto done;
2203 }
2204
2205 if (memcmp(hdr->addr1, dev->dev_addr, ETH_ALEN)) {
2206 PDEBUG(DEBUG_AP, "handle_ap_item - addr1(DA)=" MACSTR
2207 " not own MAC\n", MAC2STR(hdr->addr1));
2208 goto done;
2209 }
2210
2211 if (memcmp(hdr->addr3, dev->dev_addr, ETH_ALEN)) {
2212 PDEBUG(DEBUG_AP, "handle_ap_item - addr3(BSSID)=" MACSTR
2213 " not own MAC\n", MAC2STR(hdr->addr3));
2214 goto done;
2215 }
2216
2217 switch (stype) {
2218 case IEEE80211_STYPE_ASSOC_REQ:
2219 handle_assoc(local, skb, rx_stats, 0);
2220 break;
2221 case IEEE80211_STYPE_ASSOC_RESP:
2222 PDEBUG(DEBUG_AP, "==> ASSOC RESP (ignored)\n");
2223 break;
2224 case IEEE80211_STYPE_REASSOC_REQ:
2225 handle_assoc(local, skb, rx_stats, 1);
2226 break;
2227 case IEEE80211_STYPE_REASSOC_RESP:
2228 PDEBUG(DEBUG_AP, "==> REASSOC RESP (ignored)\n");
2229 break;
2230 case IEEE80211_STYPE_ATIM:
2231 PDEBUG(DEBUG_AP, "==> ATIM (ignored)\n");
2232 break;
2233 case IEEE80211_STYPE_DISASSOC:
2234 handle_disassoc(local, skb, rx_stats);
2235 break;
2236 case IEEE80211_STYPE_AUTH:
2237 handle_authen(local, skb, rx_stats);
2238 break;
2239 case IEEE80211_STYPE_DEAUTH:
2240 handle_deauth(local, skb, rx_stats);
2241 break;
2242 default:
2243 PDEBUG(DEBUG_AP, "Unknown mgmt frame subtype 0x%02x\n",
2244 stype >> 4);
2245 break;
2246 }
2247#endif /* PRISM2_NO_KERNEL_IEEE80211_MGMT */
2248
2249 done:
2250 dev_kfree_skb(skb);
2251}
2252
2253
2254/* Called only as a tasklet (software IRQ) */
2255void hostap_rx(struct net_device *dev, struct sk_buff *skb,
2256 struct hostap_80211_rx_status *rx_stats)
2257{
2258 struct hostap_interface *iface;
2259 local_info_t *local;
2260 u16 fc;
2261 struct ieee80211_hdr *hdr;
2262
2263 iface = netdev_priv(dev);
2264 local = iface->local;
2265
2266 if (skb->len < 16)
2267 goto drop;
2268
2269 local->stats.rx_packets++;
2270
2271 hdr = (struct ieee80211_hdr *) skb->data;
2272 fc = le16_to_cpu(hdr->frame_ctl);
2273
2274 if (local->ap->ap_policy == AP_OTHER_AP_SKIP_ALL &&
2275 WLAN_FC_GET_TYPE(fc) == IEEE80211_FTYPE_MGMT &&
2276 WLAN_FC_GET_STYPE(fc) == IEEE80211_STYPE_BEACON)
2277 goto drop;
2278
2279 skb->protocol = __constant_htons(ETH_P_HOSTAP);
2280 handle_ap_item(local, skb, rx_stats);
2281 return;
2282
2283 drop:
2284 dev_kfree_skb(skb);
2285}
2286
2287
2288/* Called only as a tasklet (software IRQ) */
2289static void schedule_packet_send(local_info_t *local, struct sta_info *sta)
2290{
2291 struct sk_buff *skb;
2292 struct ieee80211_hdr *hdr;
2293 struct hostap_80211_rx_status rx_stats;
2294
2295 if (skb_queue_empty(&sta->tx_buf))
2296 return;
2297
2298 skb = dev_alloc_skb(16);
2299 if (skb == NULL) {
2300 printk(KERN_DEBUG "%s: schedule_packet_send: skb alloc "
2301 "failed\n", local->dev->name);
2302 return;
2303 }
2304
2305 hdr = (struct ieee80211_hdr *) skb_put(skb, 16);
2306
2307 /* Generate a fake pspoll frame to start packet delivery */
2308 hdr->frame_ctl = __constant_cpu_to_le16(
2309 IEEE80211_FTYPE_CTL | IEEE80211_STYPE_PSPOLL);
2310 memcpy(hdr->addr1, local->dev->dev_addr, ETH_ALEN);
2311 memcpy(hdr->addr2, sta->addr, ETH_ALEN);
2312 hdr->duration_id = cpu_to_le16(sta->aid | BIT(15) | BIT(14));
2313
2314 PDEBUG(DEBUG_PS2, "%s: Scheduling buffered packet delivery for "
2315 "STA " MACSTR "\n", local->dev->name, MAC2STR(sta->addr));
2316
2317 skb->dev = local->dev;
2318
2319 memset(&rx_stats, 0, sizeof(rx_stats));
2320 hostap_rx(local->dev, skb, &rx_stats);
2321}
2322
2323
2324static int prism2_ap_get_sta_qual(local_info_t *local, struct sockaddr addr[],
2325 struct iw_quality qual[], int buf_size,
2326 int aplist)
2327{
2328 struct ap_data *ap = local->ap;
2329 struct list_head *ptr;
2330 int count = 0;
2331
2332 spin_lock_bh(&ap->sta_table_lock);
2333
2334 for (ptr = ap->sta_list.next; ptr != NULL && ptr != &ap->sta_list;
2335 ptr = ptr->next) {
2336 struct sta_info *sta = (struct sta_info *) ptr;
2337
2338 if (aplist && !sta->ap)
2339 continue;
2340 addr[count].sa_family = ARPHRD_ETHER;
2341 memcpy(addr[count].sa_data, sta->addr, ETH_ALEN);
2342 if (sta->last_rx_silence == 0)
2343 qual[count].qual = sta->last_rx_signal < 27 ?
2344 0 : (sta->last_rx_signal - 27) * 92 / 127;
2345 else
2346 qual[count].qual = sta->last_rx_signal -
2347 sta->last_rx_silence - 35;
2348 qual[count].level = HFA384X_LEVEL_TO_dBm(sta->last_rx_signal);
2349 qual[count].noise = HFA384X_LEVEL_TO_dBm(sta->last_rx_silence);
2350 qual[count].updated = sta->last_rx_updated;
2351
2352 sta->last_rx_updated = 0;
2353
2354 count++;
2355 if (count >= buf_size)
2356 break;
2357 }
2358 spin_unlock_bh(&ap->sta_table_lock);
2359
2360 return count;
2361}
2362
2363
2364/* Translate our list of Access Points & Stations to a card independant
2365 * format that the Wireless Tools will understand - Jean II */
2366static int prism2_ap_translate_scan(struct net_device *dev, char *buffer)
2367{
2368 struct hostap_interface *iface;
2369 local_info_t *local;
2370 struct ap_data *ap;
2371 struct list_head *ptr;
2372 struct iw_event iwe;
2373 char *current_ev = buffer;
2374 char *end_buf = buffer + IW_SCAN_MAX_DATA;
2375#if !defined(PRISM2_NO_KERNEL_IEEE80211_MGMT)
2376 char buf[64];
2377#endif
2378
2379 iface = netdev_priv(dev);
2380 local = iface->local;
2381 ap = local->ap;
2382
2383 spin_lock_bh(&ap->sta_table_lock);
2384
2385 for (ptr = ap->sta_list.next; ptr != NULL && ptr != &ap->sta_list;
2386 ptr = ptr->next) {
2387 struct sta_info *sta = (struct sta_info *) ptr;
2388
2389 /* First entry *MUST* be the AP MAC address */
2390 memset(&iwe, 0, sizeof(iwe));
2391 iwe.cmd = SIOCGIWAP;
2392 iwe.u.ap_addr.sa_family = ARPHRD_ETHER;
2393 memcpy(iwe.u.ap_addr.sa_data, sta->addr, ETH_ALEN);
2394 iwe.len = IW_EV_ADDR_LEN;
2395 current_ev = iwe_stream_add_event(current_ev, end_buf, &iwe,
2396 IW_EV_ADDR_LEN);
2397
2398 /* Use the mode to indicate if it's a station or
2399 * an Access Point */
2400 memset(&iwe, 0, sizeof(iwe));
2401 iwe.cmd = SIOCGIWMODE;
2402 if (sta->ap)
2403 iwe.u.mode = IW_MODE_MASTER;
2404 else
2405 iwe.u.mode = IW_MODE_INFRA;
2406 iwe.len = IW_EV_UINT_LEN;
2407 current_ev = iwe_stream_add_event(current_ev, end_buf, &iwe,
2408 IW_EV_UINT_LEN);
2409
2410 /* Some quality */
2411 memset(&iwe, 0, sizeof(iwe));
2412 iwe.cmd = IWEVQUAL;
2413 if (sta->last_rx_silence == 0)
2414 iwe.u.qual.qual = sta->last_rx_signal < 27 ?
2415 0 : (sta->last_rx_signal - 27) * 92 / 127;
2416 else
2417 iwe.u.qual.qual = sta->last_rx_signal -
2418 sta->last_rx_silence - 35;
2419 iwe.u.qual.level = HFA384X_LEVEL_TO_dBm(sta->last_rx_signal);
2420 iwe.u.qual.noise = HFA384X_LEVEL_TO_dBm(sta->last_rx_silence);
2421 iwe.u.qual.updated = sta->last_rx_updated;
2422 iwe.len = IW_EV_QUAL_LEN;
2423 current_ev = iwe_stream_add_event(current_ev, end_buf, &iwe,
2424 IW_EV_QUAL_LEN);
2425
2426#ifndef PRISM2_NO_KERNEL_IEEE80211_MGMT
2427 if (sta->ap) {
2428 memset(&iwe, 0, sizeof(iwe));
2429 iwe.cmd = SIOCGIWESSID;
2430 iwe.u.data.length = sta->u.ap.ssid_len;
2431 iwe.u.data.flags = 1;
2432 current_ev = iwe_stream_add_point(current_ev, end_buf,
2433 &iwe,
2434 sta->u.ap.ssid);
2435
2436 memset(&iwe, 0, sizeof(iwe));
2437 iwe.cmd = SIOCGIWENCODE;
2438 if (sta->capability & WLAN_CAPABILITY_PRIVACY)
2439 iwe.u.data.flags =
2440 IW_ENCODE_ENABLED | IW_ENCODE_NOKEY;
2441 else
2442 iwe.u.data.flags = IW_ENCODE_DISABLED;
2443 current_ev = iwe_stream_add_point(current_ev, end_buf,
2444 &iwe,
2445 sta->u.ap.ssid
2446 /* 0 byte memcpy */);
2447
2448 if (sta->u.ap.channel > 0 &&
2449 sta->u.ap.channel <= FREQ_COUNT) {
2450 memset(&iwe, 0, sizeof(iwe));
2451 iwe.cmd = SIOCGIWFREQ;
2452 iwe.u.freq.m = freq_list[sta->u.ap.channel - 1]
2453 * 100000;
2454 iwe.u.freq.e = 1;
2455 current_ev = iwe_stream_add_event(
2456 current_ev, end_buf, &iwe,
2457 IW_EV_FREQ_LEN);
2458 }
2459
2460 memset(&iwe, 0, sizeof(iwe));
2461 iwe.cmd = IWEVCUSTOM;
2462 sprintf(buf, "beacon_interval=%d",
2463 sta->listen_interval);
2464 iwe.u.data.length = strlen(buf);
2465 current_ev = iwe_stream_add_point(current_ev, end_buf,
2466 &iwe, buf);
2467 }
2468#endif /* PRISM2_NO_KERNEL_IEEE80211_MGMT */
2469
2470 sta->last_rx_updated = 0;
2471
2472 /* To be continued, we should make good use of IWEVCUSTOM */
2473 }
2474
2475 spin_unlock_bh(&ap->sta_table_lock);
2476
2477 return current_ev - buffer;
2478}
2479
2480
2481static int prism2_hostapd_add_sta(struct ap_data *ap,
2482 struct prism2_hostapd_param *param)
2483{
2484 struct sta_info *sta;
2485
2486 spin_lock_bh(&ap->sta_table_lock);
2487 sta = ap_get_sta(ap, param->sta_addr);
2488 if (sta)
2489 atomic_inc(&sta->users);
2490 spin_unlock_bh(&ap->sta_table_lock);
2491
2492 if (sta == NULL) {
2493 sta = ap_add_sta(ap, param->sta_addr);
2494 if (sta == NULL)
2495 return -1;
2496 }
2497
2498 if (!(sta->flags & WLAN_STA_ASSOC) && !sta->ap && sta->local)
2499 hostap_event_new_sta(sta->local->dev, sta);
2500
2501 sta->flags |= WLAN_STA_AUTH | WLAN_STA_ASSOC;
2502 sta->last_rx = jiffies;
2503 sta->aid = param->u.add_sta.aid;
2504 sta->capability = param->u.add_sta.capability;
2505 sta->tx_supp_rates = param->u.add_sta.tx_supp_rates;
2506 if (sta->tx_supp_rates & WLAN_RATE_1M)
2507 sta->supported_rates[0] = 2;
2508 if (sta->tx_supp_rates & WLAN_RATE_2M)
2509 sta->supported_rates[1] = 4;
2510 if (sta->tx_supp_rates & WLAN_RATE_5M5)
2511 sta->supported_rates[2] = 11;
2512 if (sta->tx_supp_rates & WLAN_RATE_11M)
2513 sta->supported_rates[3] = 22;
2514 prism2_check_tx_rates(sta);
2515 atomic_dec(&sta->users);
2516 return 0;
2517}
2518
2519
2520static int prism2_hostapd_remove_sta(struct ap_data *ap,
2521 struct prism2_hostapd_param *param)
2522{
2523 struct sta_info *sta;
2524
2525 spin_lock_bh(&ap->sta_table_lock);
2526 sta = ap_get_sta(ap, param->sta_addr);
2527 if (sta) {
2528 ap_sta_hash_del(ap, sta);
2529 list_del(&sta->list);
2530 }
2531 spin_unlock_bh(&ap->sta_table_lock);
2532
2533 if (!sta)
2534 return -ENOENT;
2535
2536 if ((sta->flags & WLAN_STA_ASSOC) && !sta->ap && sta->local)
2537 hostap_event_expired_sta(sta->local->dev, sta);
2538 ap_free_sta(ap, sta);
2539
2540 return 0;
2541}
2542
2543
2544static int prism2_hostapd_get_info_sta(struct ap_data *ap,
2545 struct prism2_hostapd_param *param)
2546{
2547 struct sta_info *sta;
2548
2549 spin_lock_bh(&ap->sta_table_lock);
2550 sta = ap_get_sta(ap, param->sta_addr);
2551 if (sta)
2552 atomic_inc(&sta->users);
2553 spin_unlock_bh(&ap->sta_table_lock);
2554
2555 if (!sta)
2556 return -ENOENT;
2557
2558 param->u.get_info_sta.inactive_sec = (jiffies - sta->last_rx) / HZ;
2559
2560 atomic_dec(&sta->users);
2561
2562 return 1;
2563}
2564
2565
2566static int prism2_hostapd_set_flags_sta(struct ap_data *ap,
2567 struct prism2_hostapd_param *param)
2568{
2569 struct sta_info *sta;
2570
2571 spin_lock_bh(&ap->sta_table_lock);
2572 sta = ap_get_sta(ap, param->sta_addr);
2573 if (sta) {
2574 sta->flags |= param->u.set_flags_sta.flags_or;
2575 sta->flags &= param->u.set_flags_sta.flags_and;
2576 }
2577 spin_unlock_bh(&ap->sta_table_lock);
2578
2579 if (!sta)
2580 return -ENOENT;
2581
2582 return 0;
2583}
2584
2585
2586static int prism2_hostapd_sta_clear_stats(struct ap_data *ap,
2587 struct prism2_hostapd_param *param)
2588{
2589 struct sta_info *sta;
2590 int rate;
2591
2592 spin_lock_bh(&ap->sta_table_lock);
2593 sta = ap_get_sta(ap, param->sta_addr);
2594 if (sta) {
2595 sta->rx_packets = sta->tx_packets = 0;
2596 sta->rx_bytes = sta->tx_bytes = 0;
2597 for (rate = 0; rate < WLAN_RATE_COUNT; rate++) {
2598 sta->tx_count[rate] = 0;
2599 sta->rx_count[rate] = 0;
2600 }
2601 }
2602 spin_unlock_bh(&ap->sta_table_lock);
2603
2604 if (!sta)
2605 return -ENOENT;
2606
2607 return 0;
2608}
2609
2610
2611static int prism2_hostapd(struct ap_data *ap,
2612 struct prism2_hostapd_param *param)
2613{
2614 switch (param->cmd) {
2615 case PRISM2_HOSTAPD_FLUSH:
2616 ap_control_kickall(ap);
2617 return 0;
2618 case PRISM2_HOSTAPD_ADD_STA:
2619 return prism2_hostapd_add_sta(ap, param);
2620 case PRISM2_HOSTAPD_REMOVE_STA:
2621 return prism2_hostapd_remove_sta(ap, param);
2622 case PRISM2_HOSTAPD_GET_INFO_STA:
2623 return prism2_hostapd_get_info_sta(ap, param);
2624 case PRISM2_HOSTAPD_SET_FLAGS_STA:
2625 return prism2_hostapd_set_flags_sta(ap, param);
2626 case PRISM2_HOSTAPD_STA_CLEAR_STATS:
2627 return prism2_hostapd_sta_clear_stats(ap, param);
2628 default:
2629 printk(KERN_WARNING "prism2_hostapd: unknown cmd=%d\n",
2630 param->cmd);
2631 return -EOPNOTSUPP;
2632 }
2633}
2634
2635
2636/* Update station info for host-based TX rate control and return current
2637 * TX rate */
2638static int ap_update_sta_tx_rate(struct sta_info *sta, struct net_device *dev)
2639{
2640 int ret = sta->tx_rate;
2641 struct hostap_interface *iface;
2642 local_info_t *local;
2643
2644 iface = netdev_priv(dev);
2645 local = iface->local;
2646
2647 sta->tx_count[sta->tx_rate_idx]++;
2648 sta->tx_since_last_failure++;
2649 sta->tx_consecutive_exc = 0;
2650 if (sta->tx_since_last_failure >= WLAN_RATE_UPDATE_COUNT &&
2651 sta->tx_rate_idx < sta->tx_max_rate) {
2652 /* use next higher rate */
2653 int old_rate, new_rate;
2654 old_rate = new_rate = sta->tx_rate_idx;
2655 while (new_rate < sta->tx_max_rate) {
2656 new_rate++;
2657 if (ap_tx_rate_ok(new_rate, sta, local)) {
2658 sta->tx_rate_idx = new_rate;
2659 break;
2660 }
2661 }
2662 if (old_rate != sta->tx_rate_idx) {
2663 switch (sta->tx_rate_idx) {
2664 case 0: sta->tx_rate = 10; break;
2665 case 1: sta->tx_rate = 20; break;
2666 case 2: sta->tx_rate = 55; break;
2667 case 3: sta->tx_rate = 110; break;
2668 default: sta->tx_rate = 0; break;
2669 }
2670 PDEBUG(DEBUG_AP, "%s: STA " MACSTR " TX rate raised to"
2671 " %d\n", dev->name, MAC2STR(sta->addr),
2672 sta->tx_rate);
2673 }
2674 sta->tx_since_last_failure = 0;
2675 }
2676
2677 return ret;
2678}
2679
2680
2681/* Called only from software IRQ. Called for each TX frame prior possible
2682 * encryption and transmit. */
2683ap_tx_ret hostap_handle_sta_tx(local_info_t *local, struct hostap_tx_data *tx)
2684{
2685 struct sta_info *sta = NULL;
2686 struct sk_buff *skb = tx->skb;
2687 int set_tim, ret;
2688 struct ieee80211_hdr *hdr;
2689 struct hostap_skb_tx_data *meta;
2690
2691 meta = (struct hostap_skb_tx_data *) skb->cb;
2692 ret = AP_TX_CONTINUE;
2693 if (local->ap == NULL || skb->len < 10 ||
2694 meta->iface->type == HOSTAP_INTERFACE_STA)
2695 goto out;
2696
2697 hdr = (struct ieee80211_hdr *) skb->data;
2698
2699 if (hdr->addr1[0] & 0x01) {
2700 /* broadcast/multicast frame - no AP related processing */
2701 goto out;
2702 }
2703
2704 /* unicast packet - check whether destination STA is associated */
2705 spin_lock(&local->ap->sta_table_lock);
2706 sta = ap_get_sta(local->ap, hdr->addr1);
2707 if (sta)
2708 atomic_inc(&sta->users);
2709 spin_unlock(&local->ap->sta_table_lock);
2710
2711 if (local->iw_mode == IW_MODE_MASTER && sta == NULL &&
2712 !(meta->flags & HOSTAP_TX_FLAGS_WDS) &&
2713 meta->iface->type != HOSTAP_INTERFACE_MASTER &&
2714 meta->iface->type != HOSTAP_INTERFACE_AP) {
2715#if 0
2716 /* This can happen, e.g., when wlan0 is added to a bridge and
2717 * bridging code does not know which port is the correct target
2718 * for a unicast frame. In this case, the packet is send to all
2719 * ports of the bridge. Since this is a valid scenario, do not
2720 * print out any errors here. */
2721 if (net_ratelimit()) {
2722 printk(KERN_DEBUG "AP: drop packet to non-associated "
2723 "STA " MACSTR "\n", MAC2STR(hdr->addr1));
2724 }
2725#endif
2726 local->ap->tx_drop_nonassoc++;
2727 ret = AP_TX_DROP;
2728 goto out;
2729 }
2730
2731 if (sta == NULL)
2732 goto out;
2733
2734 if (!(sta->flags & WLAN_STA_AUTHORIZED))
2735 ret = AP_TX_CONTINUE_NOT_AUTHORIZED;
2736
2737 /* Set tx_rate if using host-based TX rate control */
2738 if (!local->fw_tx_rate_control)
2739 local->ap->last_tx_rate = meta->rate =
2740 ap_update_sta_tx_rate(sta, local->dev);
2741
2742 if (local->iw_mode != IW_MODE_MASTER)
2743 goto out;
2744
2745 if (!(sta->flags & WLAN_STA_PS))
2746 goto out;
2747
2748 if (meta->flags & HOSTAP_TX_FLAGS_ADD_MOREDATA) {
2749 /* indicate to STA that more frames follow */
2750 hdr->frame_ctl |=
2751 __constant_cpu_to_le16(IEEE80211_FCTL_MOREDATA);
2752 }
2753
2754 if (meta->flags & HOSTAP_TX_FLAGS_BUFFERED_FRAME) {
2755 /* packet was already buffered and now send due to
2756 * PS poll, so do not rebuffer it */
2757 goto out;
2758 }
2759
2760 if (skb_queue_len(&sta->tx_buf) >= STA_MAX_TX_BUFFER) {
2761 PDEBUG(DEBUG_PS, "%s: No more space in STA (" MACSTR ")'s PS "
2762 "mode buffer\n", local->dev->name, MAC2STR(sta->addr));
2763 /* Make sure that TIM is set for the station (it might not be
2764 * after AP wlan hw reset). */
2765 /* FIX: should fix hw reset to restore bits based on STA
2766 * buffer state.. */
2767 hostap_set_tim(local, sta->aid, 1);
2768 sta->flags |= WLAN_STA_TIM;
2769 ret = AP_TX_DROP;
2770 goto out;
2771 }
2772
2773 /* STA in PS mode, buffer frame for later delivery */
2774 set_tim = skb_queue_empty(&sta->tx_buf);
2775 skb_queue_tail(&sta->tx_buf, skb);
2776 /* FIX: could save RX time to skb and expire buffered frames after
2777 * some time if STA does not poll for them */
2778
2779 if (set_tim) {
2780 if (sta->flags & WLAN_STA_TIM)
2781 PDEBUG(DEBUG_PS2, "Re-setting TIM for aid %d\n",
2782 sta->aid);
2783 hostap_set_tim(local, sta->aid, 1);
2784 sta->flags |= WLAN_STA_TIM;
2785 }
2786
2787 ret = AP_TX_BUFFERED;
2788
2789 out:
2790 if (sta != NULL) {
2791 if (ret == AP_TX_CONTINUE ||
2792 ret == AP_TX_CONTINUE_NOT_AUTHORIZED) {
2793 sta->tx_packets++;
2794 sta->tx_bytes += skb->len;
2795 sta->last_tx = jiffies;
2796 }
2797
2798 if ((ret == AP_TX_CONTINUE ||
2799 ret == AP_TX_CONTINUE_NOT_AUTHORIZED) &&
2800 sta->crypt && tx->host_encrypt) {
2801 tx->crypt = sta->crypt;
2802 tx->sta_ptr = sta; /* hostap_handle_sta_release() will
2803 * be called to release sta info
2804 * later */
2805 } else
2806 atomic_dec(&sta->users);
2807 }
2808
2809 return ret;
2810}
2811
2812
2813void hostap_handle_sta_release(void *ptr)
2814{
2815 struct sta_info *sta = ptr;
2816 atomic_dec(&sta->users);
2817}
2818
2819
2820/* Called only as a tasklet (software IRQ) */
2821void hostap_handle_sta_tx_exc(local_info_t *local, struct sk_buff *skb)
2822{
2823 struct sta_info *sta;
2824 struct ieee80211_hdr *hdr;
2825 struct hostap_skb_tx_data *meta;
2826
2827 hdr = (struct ieee80211_hdr *) skb->data;
2828 meta = (struct hostap_skb_tx_data *) skb->cb;
2829
2830 spin_lock(&local->ap->sta_table_lock);
2831 sta = ap_get_sta(local->ap, hdr->addr1);
2832 if (!sta) {
2833 spin_unlock(&local->ap->sta_table_lock);
2834 PDEBUG(DEBUG_AP, "%s: Could not find STA " MACSTR " for this "
2835 "TX error (@%lu)\n",
2836 local->dev->name, MAC2STR(hdr->addr1), jiffies);
2837 return;
2838 }
2839
2840 sta->tx_since_last_failure = 0;
2841 sta->tx_consecutive_exc++;
2842
2843 if (sta->tx_consecutive_exc >= WLAN_RATE_DECREASE_THRESHOLD &&
2844 sta->tx_rate_idx > 0 && meta->rate <= sta->tx_rate) {
2845 /* use next lower rate */
2846 int old, rate;
2847 old = rate = sta->tx_rate_idx;
2848 while (rate > 0) {
2849 rate--;
2850 if (ap_tx_rate_ok(rate, sta, local)) {
2851 sta->tx_rate_idx = rate;
2852 break;
2853 }
2854 }
2855 if (old != sta->tx_rate_idx) {
2856 switch (sta->tx_rate_idx) {
2857 case 0: sta->tx_rate = 10; break;
2858 case 1: sta->tx_rate = 20; break;
2859 case 2: sta->tx_rate = 55; break;
2860 case 3: sta->tx_rate = 110; break;
2861 default: sta->tx_rate = 0; break;
2862 }
2863 PDEBUG(DEBUG_AP, "%s: STA " MACSTR " TX rate lowered "
2864 "to %d\n", local->dev->name, MAC2STR(sta->addr),
2865 sta->tx_rate);
2866 }
2867 sta->tx_consecutive_exc = 0;
2868 }
2869 spin_unlock(&local->ap->sta_table_lock);
2870}
2871
2872
2873static void hostap_update_sta_ps2(local_info_t *local, struct sta_info *sta,
2874 int pwrmgt, int type, int stype)
2875{
2876 if (pwrmgt && !(sta->flags & WLAN_STA_PS)) {
2877 sta->flags |= WLAN_STA_PS;
2878 PDEBUG(DEBUG_PS2, "STA " MACSTR " changed to use PS "
2879 "mode (type=0x%02X, stype=0x%02X)\n",
2880 MAC2STR(sta->addr), type >> 2, stype >> 4);
2881 } else if (!pwrmgt && (sta->flags & WLAN_STA_PS)) {
2882 sta->flags &= ~WLAN_STA_PS;
2883 PDEBUG(DEBUG_PS2, "STA " MACSTR " changed to not use "
2884 "PS mode (type=0x%02X, stype=0x%02X)\n",
2885 MAC2STR(sta->addr), type >> 2, stype >> 4);
2886 if (type != IEEE80211_FTYPE_CTL ||
2887 stype != IEEE80211_STYPE_PSPOLL)
2888 schedule_packet_send(local, sta);
2889 }
2890}
2891
2892
2893/* Called only as a tasklet (software IRQ). Called for each RX frame to update
2894 * STA power saving state. pwrmgt is a flag from 802.11 frame_ctl field. */
2895int hostap_update_sta_ps(local_info_t *local, struct ieee80211_hdr *hdr)
2896{
2897 struct sta_info *sta;
2898 u16 fc;
2899
2900 spin_lock(&local->ap->sta_table_lock);
2901 sta = ap_get_sta(local->ap, hdr->addr2);
2902 if (sta)
2903 atomic_inc(&sta->users);
2904 spin_unlock(&local->ap->sta_table_lock);
2905
2906 if (!sta)
2907 return -1;
2908
2909 fc = le16_to_cpu(hdr->frame_ctl);
2910 hostap_update_sta_ps2(local, sta, fc & IEEE80211_FCTL_PM,
2911 WLAN_FC_GET_TYPE(fc), WLAN_FC_GET_STYPE(fc));
2912
2913 atomic_dec(&sta->users);
2914 return 0;
2915}
2916
2917
2918/* Called only as a tasklet (software IRQ). Called for each RX frame after
2919 * getting RX header and payload from hardware. */
2920ap_rx_ret hostap_handle_sta_rx(local_info_t *local, struct net_device *dev,
2921 struct sk_buff *skb,
2922 struct hostap_80211_rx_status *rx_stats,
2923 int wds)
2924{
2925 int ret;
2926 struct sta_info *sta;
2927 u16 fc, type, stype;
2928 struct ieee80211_hdr *hdr;
2929
2930 if (local->ap == NULL)
2931 return AP_RX_CONTINUE;
2932
2933 hdr = (struct ieee80211_hdr *) skb->data;
2934
2935 fc = le16_to_cpu(hdr->frame_ctl);
2936 type = WLAN_FC_GET_TYPE(fc);
2937 stype = WLAN_FC_GET_STYPE(fc);
2938
2939 spin_lock(&local->ap->sta_table_lock);
2940 sta = ap_get_sta(local->ap, hdr->addr2);
2941 if (sta)
2942 atomic_inc(&sta->users);
2943 spin_unlock(&local->ap->sta_table_lock);
2944
2945 if (sta && !(sta->flags & WLAN_STA_AUTHORIZED))
2946 ret = AP_RX_CONTINUE_NOT_AUTHORIZED;
2947 else
2948 ret = AP_RX_CONTINUE;
2949
2950
2951 if (fc & IEEE80211_FCTL_TODS) {
2952 if (!wds && (sta == NULL || !(sta->flags & WLAN_STA_ASSOC))) {
2953 if (local->hostapd) {
2954 prism2_rx_80211(local->apdev, skb, rx_stats,
2955 PRISM2_RX_NON_ASSOC);
2956#ifndef PRISM2_NO_KERNEL_IEEE80211_MGMT
2957 } else {
2958 printk(KERN_DEBUG "%s: dropped received packet"
2959 " from non-associated STA " MACSTR
2960 " (type=0x%02x, subtype=0x%02x)\n",
2961 dev->name, MAC2STR(hdr->addr2),
2962 type >> 2, stype >> 4);
2963 hostap_rx(dev, skb, rx_stats);
2964#endif /* PRISM2_NO_KERNEL_IEEE80211_MGMT */
2965 }
2966 ret = AP_RX_EXIT;
2967 goto out;
2968 }
2969 } else if (fc & IEEE80211_FCTL_FROMDS) {
2970 if (!wds) {
2971 /* FromDS frame - not for us; probably
2972 * broadcast/multicast in another BSS - drop */
2973 if (memcmp(hdr->addr1, dev->dev_addr, ETH_ALEN) == 0) {
2974 printk(KERN_DEBUG "Odd.. FromDS packet "
2975 "received with own BSSID\n");
2976 hostap_dump_rx_80211(dev->name, skb, rx_stats);
2977 }
2978 ret = AP_RX_DROP;
2979 goto out;
2980 }
2981 } else if (stype == IEEE80211_STYPE_NULLFUNC && sta == NULL &&
2982 memcmp(hdr->addr1, dev->dev_addr, ETH_ALEN) == 0) {
2983
2984 if (local->hostapd) {
2985 prism2_rx_80211(local->apdev, skb, rx_stats,
2986 PRISM2_RX_NON_ASSOC);
2987#ifndef PRISM2_NO_KERNEL_IEEE80211_MGMT
2988 } else {
2989 /* At least Lucent f/w seems to send data::nullfunc
2990 * frames with no ToDS flag when the current AP returns
2991 * after being unavailable for some time. Speed up
2992 * re-association by informing the station about it not
2993 * being associated. */
2994 printk(KERN_DEBUG "%s: rejected received nullfunc "
2995 "frame without ToDS from not associated STA "
2996 MACSTR "\n",
2997 dev->name, MAC2STR(hdr->addr2));
2998 hostap_rx(dev, skb, rx_stats);
2999#endif /* PRISM2_NO_KERNEL_IEEE80211_MGMT */
3000 }
3001 ret = AP_RX_EXIT;
3002 goto out;
3003 } else if (stype == IEEE80211_STYPE_NULLFUNC) {
3004 /* At least Lucent cards seem to send periodic nullfunc
3005 * frames with ToDS. Let these through to update SQ
3006 * stats and PS state. Nullfunc frames do not contain
3007 * any data and they will be dropped below. */
3008 } else {
3009 /* If BSSID (Addr3) is foreign, this frame is a normal
3010 * broadcast frame from an IBSS network. Drop it silently.
3011 * If BSSID is own, report the dropping of this frame. */
3012 if (memcmp(hdr->addr3, dev->dev_addr, ETH_ALEN) == 0) {
3013 printk(KERN_DEBUG "%s: dropped received packet from "
3014 MACSTR " with no ToDS flag (type=0x%02x, "
3015 "subtype=0x%02x)\n", dev->name,
3016 MAC2STR(hdr->addr2), type >> 2, stype >> 4);
3017 hostap_dump_rx_80211(dev->name, skb, rx_stats);
3018 }
3019 ret = AP_RX_DROP;
3020 goto out;
3021 }
3022
3023 if (sta) {
3024 hostap_update_sta_ps2(local, sta, fc & IEEE80211_FCTL_PM,
3025 type, stype);
3026
3027 sta->rx_packets++;
3028 sta->rx_bytes += skb->len;
3029 sta->last_rx = jiffies;
3030 }
3031
3032 if (local->ap->nullfunc_ack && stype == IEEE80211_STYPE_NULLFUNC &&
3033 fc & IEEE80211_FCTL_TODS) {
3034 if (local->hostapd) {
3035 prism2_rx_80211(local->apdev, skb, rx_stats,
3036 PRISM2_RX_NULLFUNC_ACK);
3037#ifndef PRISM2_NO_KERNEL_IEEE80211_MGMT
3038 } else {
3039 /* some STA f/w's seem to require control::ACK frame
3040 * for data::nullfunc, but Prism2 f/w 0.8.0 (at least
3041 * from Compaq) does not send this.. Try to generate
3042 * ACK for these frames from the host driver to make
3043 * power saving work with, e.g., Lucent WaveLAN f/w */
3044 hostap_rx(dev, skb, rx_stats);
3045#endif /* PRISM2_NO_KERNEL_IEEE80211_MGMT */
3046 }
3047 ret = AP_RX_EXIT;
3048 goto out;
3049 }
3050
3051 out:
3052 if (sta)
3053 atomic_dec(&sta->users);
3054
3055 return ret;
3056}
3057
3058
3059/* Called only as a tasklet (software IRQ) */
3060int hostap_handle_sta_crypto(local_info_t *local,
3061 struct ieee80211_hdr *hdr,
3062 struct ieee80211_crypt_data **crypt,
3063 void **sta_ptr)
3064{
3065 struct sta_info *sta;
3066
3067 spin_lock(&local->ap->sta_table_lock);
3068 sta = ap_get_sta(local->ap, hdr->addr2);
3069 if (sta)
3070 atomic_inc(&sta->users);
3071 spin_unlock(&local->ap->sta_table_lock);
3072
3073 if (!sta)
3074 return -1;
3075
3076 if (sta->crypt) {
3077 *crypt = sta->crypt;
3078 *sta_ptr = sta;
3079 /* hostap_handle_sta_release() will be called to release STA
3080 * info */
3081 } else
3082 atomic_dec(&sta->users);
3083
3084 return 0;
3085}
3086
3087
3088/* Called only as a tasklet (software IRQ) */
3089int hostap_is_sta_assoc(struct ap_data *ap, u8 *sta_addr)
3090{
3091 struct sta_info *sta;
3092 int ret = 0;
3093
3094 spin_lock(&ap->sta_table_lock);
3095 sta = ap_get_sta(ap, sta_addr);
3096 if (sta != NULL && (sta->flags & WLAN_STA_ASSOC) && !sta->ap)
3097 ret = 1;
3098 spin_unlock(&ap->sta_table_lock);
3099
3100 return ret;
3101}
3102
3103
3104/* Called only as a tasklet (software IRQ) */
3105int hostap_is_sta_authorized(struct ap_data *ap, u8 *sta_addr)
3106{
3107 struct sta_info *sta;
3108 int ret = 0;
3109
3110 spin_lock(&ap->sta_table_lock);
3111 sta = ap_get_sta(ap, sta_addr);
3112 if (sta != NULL && (sta->flags & WLAN_STA_ASSOC) && !sta->ap &&
3113 ((sta->flags & WLAN_STA_AUTHORIZED) ||
3114 ap->local->ieee_802_1x == 0))
3115 ret = 1;
3116 spin_unlock(&ap->sta_table_lock);
3117
3118 return ret;
3119}
3120
3121
3122/* Called only as a tasklet (software IRQ) */
3123int hostap_add_sta(struct ap_data *ap, u8 *sta_addr)
3124{
3125 struct sta_info *sta;
3126 int ret = 1;
3127
3128 if (!ap)
3129 return -1;
3130
3131 spin_lock(&ap->sta_table_lock);
3132 sta = ap_get_sta(ap, sta_addr);
3133 if (sta)
3134 ret = 0;
3135 spin_unlock(&ap->sta_table_lock);
3136
3137 if (ret == 1) {
3138 sta = ap_add_sta(ap, sta_addr);
3139 if (!sta)
3140 ret = -1;
3141 sta->flags = WLAN_STA_AUTH | WLAN_STA_ASSOC;
3142 sta->ap = 1;
3143 memset(sta->supported_rates, 0, sizeof(sta->supported_rates));
3144 /* No way of knowing which rates are supported since we did not
3145 * get supported rates element from beacon/assoc req. Assume
3146 * that remote end supports all 802.11b rates. */
3147 sta->supported_rates[0] = 0x82;
3148 sta->supported_rates[1] = 0x84;
3149 sta->supported_rates[2] = 0x0b;
3150 sta->supported_rates[3] = 0x16;
3151 sta->tx_supp_rates = WLAN_RATE_1M | WLAN_RATE_2M |
3152 WLAN_RATE_5M5 | WLAN_RATE_11M;
3153 sta->tx_rate = 110;
3154 sta->tx_max_rate = sta->tx_rate_idx = 3;
3155 }
3156
3157 return ret;
3158}
3159
3160
3161/* Called only as a tasklet (software IRQ) */
3162int hostap_update_rx_stats(struct ap_data *ap,
3163 struct ieee80211_hdr *hdr,
3164 struct hostap_80211_rx_status *rx_stats)
3165{
3166 struct sta_info *sta;
3167
3168 if (!ap)
3169 return -1;
3170
3171 spin_lock(&ap->sta_table_lock);
3172 sta = ap_get_sta(ap, hdr->addr2);
3173 if (sta) {
3174 sta->last_rx_silence = rx_stats->noise;
3175 sta->last_rx_signal = rx_stats->signal;
3176 sta->last_rx_rate = rx_stats->rate;
3177 sta->last_rx_updated = 7;
3178 if (rx_stats->rate == 10)
3179 sta->rx_count[0]++;
3180 else if (rx_stats->rate == 20)
3181 sta->rx_count[1]++;
3182 else if (rx_stats->rate == 55)
3183 sta->rx_count[2]++;
3184 else if (rx_stats->rate == 110)
3185 sta->rx_count[3]++;
3186 }
3187 spin_unlock(&ap->sta_table_lock);
3188
3189 return sta ? 0 : -1;
3190}
3191
3192
3193void hostap_update_rates(local_info_t *local)
3194{
3195 struct list_head *ptr;
3196 struct ap_data *ap = local->ap;
3197
3198 if (!ap)
3199 return;
3200
3201 spin_lock_bh(&ap->sta_table_lock);
3202 for (ptr = ap->sta_list.next; ptr != &ap->sta_list; ptr = ptr->next) {
3203 struct sta_info *sta = (struct sta_info *) ptr;
3204 prism2_check_tx_rates(sta);
3205 }
3206 spin_unlock_bh(&ap->sta_table_lock);
3207}
3208
3209
3210static void * ap_crypt_get_ptrs(struct ap_data *ap, u8 *addr, int permanent,
3211 struct ieee80211_crypt_data ***crypt)
3212{
3213 struct sta_info *sta;
3214
3215 spin_lock_bh(&ap->sta_table_lock);
3216 sta = ap_get_sta(ap, addr);
3217 if (sta)
3218 atomic_inc(&sta->users);
3219 spin_unlock_bh(&ap->sta_table_lock);
3220
3221 if (!sta && permanent)
3222 sta = ap_add_sta(ap, addr);
3223
3224 if (!sta)
3225 return NULL;
3226
3227 if (permanent)
3228 sta->flags |= WLAN_STA_PERM;
3229
3230 *crypt = &sta->crypt;
3231
3232 return sta;
3233}
3234
3235
3236void hostap_add_wds_links(local_info_t *local)
3237{
3238 struct ap_data *ap = local->ap;
3239 struct list_head *ptr;
3240
3241 spin_lock_bh(&ap->sta_table_lock);
3242 list_for_each(ptr, &ap->sta_list) {
3243 struct sta_info *sta = list_entry(ptr, struct sta_info, list);
3244 if (sta->ap)
3245 hostap_wds_link_oper(local, sta->addr, WDS_ADD);
3246 }
3247 spin_unlock_bh(&ap->sta_table_lock);
3248
3249 schedule_work(&local->ap->wds_oper_queue);
3250}
3251
3252
3253void hostap_wds_link_oper(local_info_t *local, u8 *addr, wds_oper_type type)
3254{
3255 struct wds_oper_data *entry;
3256
3257 entry = kmalloc(sizeof(*entry), GFP_ATOMIC);
3258 if (!entry)
3259 return;
3260 memcpy(entry->addr, addr, ETH_ALEN);
3261 entry->type = type;
3262 spin_lock_bh(&local->lock);
3263 entry->next = local->ap->wds_oper_entries;
3264 local->ap->wds_oper_entries = entry;
3265 spin_unlock_bh(&local->lock);
3266
3267 schedule_work(&local->ap->wds_oper_queue);
3268}
3269
3270
3271EXPORT_SYMBOL(hostap_init_data);
3272EXPORT_SYMBOL(hostap_init_ap_proc);
3273EXPORT_SYMBOL(hostap_free_data);
3274EXPORT_SYMBOL(hostap_check_sta_fw_version);
3275EXPORT_SYMBOL(hostap_handle_sta_tx);
3276EXPORT_SYMBOL(hostap_handle_sta_release);
3277EXPORT_SYMBOL(hostap_handle_sta_tx_exc);
3278EXPORT_SYMBOL(hostap_update_sta_ps);
3279EXPORT_SYMBOL(hostap_handle_sta_rx);
3280EXPORT_SYMBOL(hostap_is_sta_assoc);
3281EXPORT_SYMBOL(hostap_is_sta_authorized);
3282EXPORT_SYMBOL(hostap_add_sta);
3283EXPORT_SYMBOL(hostap_update_rates);
3284EXPORT_SYMBOL(hostap_add_wds_links);
3285EXPORT_SYMBOL(hostap_wds_link_oper);
3286#ifndef PRISM2_NO_KERNEL_IEEE80211_MGMT
3287EXPORT_SYMBOL(hostap_deauth_all_stas);
3288#endif /* PRISM2_NO_KERNEL_IEEE80211_MGMT */
diff --git a/drivers/net/wireless/hostap/hostap_ap.h b/drivers/net/wireless/hostap/hostap_ap.h
new file mode 100644
index 000000000000..816a52bcea8f
--- /dev/null
+++ b/drivers/net/wireless/hostap/hostap_ap.h
@@ -0,0 +1,261 @@
1#ifndef HOSTAP_AP_H
2#define HOSTAP_AP_H
3
4/* AP data structures for STAs */
5
6/* maximum number of frames to buffer per STA */
7#define STA_MAX_TX_BUFFER 32
8
9/* STA flags */
10#define WLAN_STA_AUTH BIT(0)
11#define WLAN_STA_ASSOC BIT(1)
12#define WLAN_STA_PS BIT(2)
13#define WLAN_STA_TIM BIT(3) /* TIM bit is on for PS stations */
14#define WLAN_STA_PERM BIT(4) /* permanent; do not remove entry on expiration */
15#define WLAN_STA_AUTHORIZED BIT(5) /* If 802.1X is used, this flag is
16 * controlling whether STA is authorized to
17 * send and receive non-IEEE 802.1X frames
18 */
19#define WLAN_STA_PENDING_POLL BIT(6) /* pending activity poll not ACKed */
20
21#define WLAN_RATE_1M BIT(0)
22#define WLAN_RATE_2M BIT(1)
23#define WLAN_RATE_5M5 BIT(2)
24#define WLAN_RATE_11M BIT(3)
25#define WLAN_RATE_COUNT 4
26
27/* Maximum size of Supported Rates info element. IEEE 802.11 has a limit of 8,
28 * but some pre-standard IEEE 802.11g products use longer elements. */
29#define WLAN_SUPP_RATES_MAX 32
30
31/* Try to increase TX rate after # successfully sent consecutive packets */
32#define WLAN_RATE_UPDATE_COUNT 50
33
34/* Decrease TX rate after # consecutive dropped packets */
35#define WLAN_RATE_DECREASE_THRESHOLD 2
36
37struct sta_info {
38 struct list_head list;
39 struct sta_info *hnext; /* next entry in hash table list */
40 atomic_t users; /* number of users (do not remove if > 0) */
41 struct proc_dir_entry *proc;
42
43 u8 addr[6];
44 u16 aid; /* STA's unique AID (1 .. 2007) or 0 if not yet assigned */
45 u32 flags;
46 u16 capability;
47 u16 listen_interval; /* or beacon_int for APs */
48 u8 supported_rates[WLAN_SUPP_RATES_MAX];
49
50 unsigned long last_auth;
51 unsigned long last_assoc;
52 unsigned long last_rx;
53 unsigned long last_tx;
54 unsigned long rx_packets, tx_packets;
55 unsigned long rx_bytes, tx_bytes;
56 struct sk_buff_head tx_buf;
57 /* FIX: timeout buffers with an expiry time somehow derived from
58 * listen_interval */
59
60 s8 last_rx_silence; /* Noise in dBm */
61 s8 last_rx_signal; /* Signal strength in dBm */
62 u8 last_rx_rate; /* TX rate in 0.1 Mbps */
63 u8 last_rx_updated; /* IWSPY's struct iw_quality::updated */
64
65 u8 tx_supp_rates; /* bit field of supported TX rates */
66 u8 tx_rate; /* current TX rate (in 0.1 Mbps) */
67 u8 tx_rate_idx; /* current TX rate (WLAN_RATE_*) */
68 u8 tx_max_rate; /* max TX rate (WLAN_RATE_*) */
69 u32 tx_count[WLAN_RATE_COUNT]; /* number of frames sent (per rate) */
70 u32 rx_count[WLAN_RATE_COUNT]; /* number of frames received (per rate)
71 */
72 u32 tx_since_last_failure;
73 u32 tx_consecutive_exc;
74
75 struct ieee80211_crypt_data *crypt;
76
77 int ap; /* whether this station is an AP */
78
79 local_info_t *local;
80
81#ifndef PRISM2_NO_KERNEL_IEEE80211_MGMT
82 union {
83 struct {
84 char *challenge; /* shared key authentication
85 * challenge */
86 } sta;
87 struct {
88 int ssid_len;
89 unsigned char ssid[MAX_SSID_LEN + 1]; /* AP's ssid */
90 int channel;
91 unsigned long last_beacon; /* last RX beacon time */
92 } ap;
93 } u;
94
95 struct timer_list timer;
96 enum { STA_NULLFUNC = 0, STA_DISASSOC, STA_DEAUTH } timeout_next;
97#endif /* PRISM2_NO_KERNEL_IEEE80211_MGMT */
98};
99
100
101#define MAX_STA_COUNT 1024
102
103/* Maximum number of AIDs to use for STAs; must be 2007 or lower
104 * (8802.11 limitation) */
105#define MAX_AID_TABLE_SIZE 128
106
107#define STA_HASH_SIZE 256
108#define STA_HASH(sta) (sta[5])
109
110
111/* Default value for maximum station inactivity. After AP_MAX_INACTIVITY_SEC
112 * has passed since last received frame from the station, a nullfunc data
113 * frame is sent to the station. If this frame is not acknowledged and no other
114 * frames have been received, the station will be disassociated after
115 * AP_DISASSOC_DELAY. Similarily, a the station will be deauthenticated after
116 * AP_DEAUTH_DELAY. AP_TIMEOUT_RESOLUTION is the resolution that is used with
117 * max inactivity timer. */
118#define AP_MAX_INACTIVITY_SEC (5 * 60)
119#define AP_DISASSOC_DELAY (HZ)
120#define AP_DEAUTH_DELAY (HZ)
121
122/* ap_policy: whether to accept frames to/from other APs/IBSS */
123typedef enum {
124 AP_OTHER_AP_SKIP_ALL = 0,
125 AP_OTHER_AP_SAME_SSID = 1,
126 AP_OTHER_AP_ALL = 2,
127 AP_OTHER_AP_EVEN_IBSS = 3
128} ap_policy_enum;
129
130#define PRISM2_AUTH_OPEN BIT(0)
131#define PRISM2_AUTH_SHARED_KEY BIT(1)
132
133
134/* MAC address-based restrictions */
135struct mac_entry {
136 struct list_head list;
137 u8 addr[6];
138};
139
140struct mac_restrictions {
141 enum { MAC_POLICY_OPEN = 0, MAC_POLICY_ALLOW, MAC_POLICY_DENY } policy;
142 unsigned int entries;
143 struct list_head mac_list;
144 spinlock_t lock;
145};
146
147
148struct add_sta_proc_data {
149 u8 addr[ETH_ALEN];
150 struct add_sta_proc_data *next;
151};
152
153
154typedef enum { WDS_ADD, WDS_DEL } wds_oper_type;
155struct wds_oper_data {
156 wds_oper_type type;
157 u8 addr[ETH_ALEN];
158 struct wds_oper_data *next;
159};
160
161
162struct ap_data {
163 int initialized; /* whether ap_data has been initialized */
164 local_info_t *local;
165 int bridge_packets; /* send packet to associated STAs directly to the
166 * wireless media instead of higher layers in the
167 * kernel */
168 unsigned int bridged_unicast; /* number of unicast frames bridged on
169 * wireless media */
170 unsigned int bridged_multicast; /* number of non-unicast frames
171 * bridged on wireless media */
172 unsigned int tx_drop_nonassoc; /* number of unicast TX packets dropped
173 * because they were to an address that
174 * was not associated */
175 int nullfunc_ack; /* use workaround for nullfunc frame ACKs */
176
177 spinlock_t sta_table_lock;
178 int num_sta; /* number of entries in sta_list */
179 struct list_head sta_list; /* STA info list head */
180 struct sta_info *sta_hash[STA_HASH_SIZE];
181
182 struct proc_dir_entry *proc;
183
184 ap_policy_enum ap_policy;
185 unsigned int max_inactivity;
186 int autom_ap_wds;
187
188 struct mac_restrictions mac_restrictions; /* MAC-based auth */
189 int last_tx_rate;
190
191 struct work_struct add_sta_proc_queue;
192 struct add_sta_proc_data *add_sta_proc_entries;
193
194 struct work_struct wds_oper_queue;
195 struct wds_oper_data *wds_oper_entries;
196
197 u16 tx_callback_idx;
198
199#ifndef PRISM2_NO_KERNEL_IEEE80211_MGMT
200 /* pointers to STA info; based on allocated AID or NULL if AID free
201 * AID is in the range 1-2007, so sta_aid[0] corresponders to AID 1
202 * and so on
203 */
204 struct sta_info *sta_aid[MAX_AID_TABLE_SIZE];
205
206 u16 tx_callback_auth, tx_callback_assoc, tx_callback_poll;
207
208 /* WEP operations for generating challenges to be used with shared key
209 * authentication */
210 struct ieee80211_crypto_ops *crypt;
211 void *crypt_priv;
212#endif /* PRISM2_NO_KERNEL_IEEE80211_MGMT */
213};
214
215
216void hostap_rx(struct net_device *dev, struct sk_buff *skb,
217 struct hostap_80211_rx_status *rx_stats);
218void hostap_init_data(local_info_t *local);
219void hostap_init_ap_proc(local_info_t *local);
220void hostap_free_data(struct ap_data *ap);
221void hostap_check_sta_fw_version(struct ap_data *ap, int sta_fw_ver);
222
223typedef enum {
224 AP_TX_CONTINUE, AP_TX_DROP, AP_TX_RETRY, AP_TX_BUFFERED,
225 AP_TX_CONTINUE_NOT_AUTHORIZED
226} ap_tx_ret;
227struct hostap_tx_data {
228 struct sk_buff *skb;
229 int host_encrypt;
230 struct ieee80211_crypt_data *crypt;
231 void *sta_ptr;
232};
233ap_tx_ret hostap_handle_sta_tx(local_info_t *local, struct hostap_tx_data *tx);
234void hostap_handle_sta_release(void *ptr);
235void hostap_handle_sta_tx_exc(local_info_t *local, struct sk_buff *skb);
236int hostap_update_sta_ps(local_info_t *local, struct ieee80211_hdr *hdr);
237typedef enum {
238 AP_RX_CONTINUE, AP_RX_DROP, AP_RX_EXIT, AP_RX_CONTINUE_NOT_AUTHORIZED
239} ap_rx_ret;
240ap_rx_ret hostap_handle_sta_rx(local_info_t *local, struct net_device *dev,
241 struct sk_buff *skb,
242 struct hostap_80211_rx_status *rx_stats,
243 int wds);
244int hostap_handle_sta_crypto(local_info_t *local, struct ieee80211_hdr *hdr,
245 struct ieee80211_crypt_data **crypt,
246 void **sta_ptr);
247int hostap_is_sta_assoc(struct ap_data *ap, u8 *sta_addr);
248int hostap_is_sta_authorized(struct ap_data *ap, u8 *sta_addr);
249int hostap_add_sta(struct ap_data *ap, u8 *sta_addr);
250int hostap_update_rx_stats(struct ap_data *ap, struct ieee80211_hdr *hdr,
251 struct hostap_80211_rx_status *rx_stats);
252void hostap_update_rates(local_info_t *local);
253void hostap_add_wds_links(local_info_t *local);
254void hostap_wds_link_oper(local_info_t *local, u8 *addr, wds_oper_type type);
255
256#ifndef PRISM2_NO_KERNEL_IEEE80211_MGMT
257void hostap_deauth_all_stas(struct net_device *dev, struct ap_data *ap,
258 int resend);
259#endif /* PRISM2_NO_KERNEL_IEEE80211_MGMT */
260
261#endif /* HOSTAP_AP_H */
diff --git a/drivers/net/wireless/hostap/hostap_common.h b/drivers/net/wireless/hostap/hostap_common.h
new file mode 100644
index 000000000000..6f4fa9dc308f
--- /dev/null
+++ b/drivers/net/wireless/hostap/hostap_common.h
@@ -0,0 +1,435 @@
1#ifndef HOSTAP_COMMON_H
2#define HOSTAP_COMMON_H
3
4#define BIT(x) (1 << (x))
5
6#define MAC2STR(a) (a)[0], (a)[1], (a)[2], (a)[3], (a)[4], (a)[5]
7#define MACSTR "%02x:%02x:%02x:%02x:%02x:%02x"
8
9
10/* IEEE 802.11 defines */
11
12/* Information Element IDs */
13#define WLAN_EID_SSID 0
14#define WLAN_EID_SUPP_RATES 1
15#define WLAN_EID_FH_PARAMS 2
16#define WLAN_EID_DS_PARAMS 3
17#define WLAN_EID_CF_PARAMS 4
18#define WLAN_EID_TIM 5
19#define WLAN_EID_IBSS_PARAMS 6
20#define WLAN_EID_CHALLENGE 16
21#define WLAN_EID_RSN 48
22#define WLAN_EID_GENERIC 221
23
24
25/* HFA384X Configuration RIDs */
26#define HFA384X_RID_CNFPORTTYPE 0xFC00
27#define HFA384X_RID_CNFOWNMACADDR 0xFC01
28#define HFA384X_RID_CNFDESIREDSSID 0xFC02
29#define HFA384X_RID_CNFOWNCHANNEL 0xFC03
30#define HFA384X_RID_CNFOWNSSID 0xFC04
31#define HFA384X_RID_CNFOWNATIMWINDOW 0xFC05
32#define HFA384X_RID_CNFSYSTEMSCALE 0xFC06
33#define HFA384X_RID_CNFMAXDATALEN 0xFC07
34#define HFA384X_RID_CNFWDSADDRESS 0xFC08
35#define HFA384X_RID_CNFPMENABLED 0xFC09
36#define HFA384X_RID_CNFPMEPS 0xFC0A
37#define HFA384X_RID_CNFMULTICASTRECEIVE 0xFC0B
38#define HFA384X_RID_CNFMAXSLEEPDURATION 0xFC0C
39#define HFA384X_RID_CNFPMHOLDOVERDURATION 0xFC0D
40#define HFA384X_RID_CNFOWNNAME 0xFC0E
41#define HFA384X_RID_CNFOWNDTIMPERIOD 0xFC10
42#define HFA384X_RID_CNFWDSADDRESS1 0xFC11 /* AP f/w only */
43#define HFA384X_RID_CNFWDSADDRESS2 0xFC12 /* AP f/w only */
44#define HFA384X_RID_CNFWDSADDRESS3 0xFC13 /* AP f/w only */
45#define HFA384X_RID_CNFWDSADDRESS4 0xFC14 /* AP f/w only */
46#define HFA384X_RID_CNFWDSADDRESS5 0xFC15 /* AP f/w only */
47#define HFA384X_RID_CNFWDSADDRESS6 0xFC16 /* AP f/w only */
48#define HFA384X_RID_CNFMULTICASTPMBUFFERING 0xFC17 /* AP f/w only */
49#define HFA384X_RID_UNKNOWN1 0xFC20
50#define HFA384X_RID_UNKNOWN2 0xFC21
51#define HFA384X_RID_CNFWEPDEFAULTKEYID 0xFC23
52#define HFA384X_RID_CNFDEFAULTKEY0 0xFC24
53#define HFA384X_RID_CNFDEFAULTKEY1 0xFC25
54#define HFA384X_RID_CNFDEFAULTKEY2 0xFC26
55#define HFA384X_RID_CNFDEFAULTKEY3 0xFC27
56#define HFA384X_RID_CNFWEPFLAGS 0xFC28
57#define HFA384X_RID_CNFWEPKEYMAPPINGTABLE 0xFC29
58#define HFA384X_RID_CNFAUTHENTICATION 0xFC2A
59#define HFA384X_RID_CNFMAXASSOCSTA 0xFC2B /* AP f/w only */
60#define HFA384X_RID_CNFTXCONTROL 0xFC2C
61#define HFA384X_RID_CNFROAMINGMODE 0xFC2D
62#define HFA384X_RID_CNFHOSTAUTHENTICATION 0xFC2E /* AP f/w only */
63#define HFA384X_RID_CNFRCVCRCERROR 0xFC30
64#define HFA384X_RID_CNFMMLIFE 0xFC31
65#define HFA384X_RID_CNFALTRETRYCOUNT 0xFC32
66#define HFA384X_RID_CNFBEACONINT 0xFC33
67#define HFA384X_RID_CNFAPPCFINFO 0xFC34 /* AP f/w only */
68#define HFA384X_RID_CNFSTAPCFINFO 0xFC35
69#define HFA384X_RID_CNFPRIORITYQUSAGE 0xFC37
70#define HFA384X_RID_CNFTIMCTRL 0xFC40
71#define HFA384X_RID_UNKNOWN3 0xFC41 /* added in STA f/w 0.7.x */
72#define HFA384X_RID_CNFTHIRTY2TALLY 0xFC42 /* added in STA f/w 0.8.0 */
73#define HFA384X_RID_CNFENHSECURITY 0xFC43 /* AP f/w or STA f/w >= 1.6.3 */
74#define HFA384X_RID_CNFDBMADJUST 0xFC46 /* added in STA f/w 1.3.1 */
75#define HFA384X_RID_GENERICELEMENT 0xFC48 /* added in STA f/w 1.7.0;
76 * write only */
77#define HFA384X_RID_PROPAGATIONDELAY 0xFC49 /* added in STA f/w 1.7.6 */
78#define HFA384X_RID_GROUPADDRESSES 0xFC80
79#define HFA384X_RID_CREATEIBSS 0xFC81
80#define HFA384X_RID_FRAGMENTATIONTHRESHOLD 0xFC82
81#define HFA384X_RID_RTSTHRESHOLD 0xFC83
82#define HFA384X_RID_TXRATECONTROL 0xFC84
83#define HFA384X_RID_PROMISCUOUSMODE 0xFC85
84#define HFA384X_RID_FRAGMENTATIONTHRESHOLD0 0xFC90 /* AP f/w only */
85#define HFA384X_RID_FRAGMENTATIONTHRESHOLD1 0xFC91 /* AP f/w only */
86#define HFA384X_RID_FRAGMENTATIONTHRESHOLD2 0xFC92 /* AP f/w only */
87#define HFA384X_RID_FRAGMENTATIONTHRESHOLD3 0xFC93 /* AP f/w only */
88#define HFA384X_RID_FRAGMENTATIONTHRESHOLD4 0xFC94 /* AP f/w only */
89#define HFA384X_RID_FRAGMENTATIONTHRESHOLD5 0xFC95 /* AP f/w only */
90#define HFA384X_RID_FRAGMENTATIONTHRESHOLD6 0xFC96 /* AP f/w only */
91#define HFA384X_RID_RTSTHRESHOLD0 0xFC97 /* AP f/w only */
92#define HFA384X_RID_RTSTHRESHOLD1 0xFC98 /* AP f/w only */
93#define HFA384X_RID_RTSTHRESHOLD2 0xFC99 /* AP f/w only */
94#define HFA384X_RID_RTSTHRESHOLD3 0xFC9A /* AP f/w only */
95#define HFA384X_RID_RTSTHRESHOLD4 0xFC9B /* AP f/w only */
96#define HFA384X_RID_RTSTHRESHOLD5 0xFC9C /* AP f/w only */
97#define HFA384X_RID_RTSTHRESHOLD6 0xFC9D /* AP f/w only */
98#define HFA384X_RID_TXRATECONTROL0 0xFC9E /* AP f/w only */
99#define HFA384X_RID_TXRATECONTROL1 0xFC9F /* AP f/w only */
100#define HFA384X_RID_TXRATECONTROL2 0xFCA0 /* AP f/w only */
101#define HFA384X_RID_TXRATECONTROL3 0xFCA1 /* AP f/w only */
102#define HFA384X_RID_TXRATECONTROL4 0xFCA2 /* AP f/w only */
103#define HFA384X_RID_TXRATECONTROL5 0xFCA3 /* AP f/w only */
104#define HFA384X_RID_TXRATECONTROL6 0xFCA4 /* AP f/w only */
105#define HFA384X_RID_CNFSHORTPREAMBLE 0xFCB0
106#define HFA384X_RID_CNFEXCLUDELONGPREAMBLE 0xFCB1
107#define HFA384X_RID_CNFAUTHENTICATIONRSPTO 0xFCB2
108#define HFA384X_RID_CNFBASICRATES 0xFCB3
109#define HFA384X_RID_CNFSUPPORTEDRATES 0xFCB4
110#define HFA384X_RID_CNFFALLBACKCTRL 0xFCB5 /* added in STA f/w 1.3.1 */
111#define HFA384X_RID_WEPKEYDISABLE 0xFCB6 /* added in STA f/w 1.3.1 */
112#define HFA384X_RID_WEPKEYMAPINDEX 0xFCB7 /* ? */
113#define HFA384X_RID_BROADCASTKEYID 0xFCB8 /* ? */
114#define HFA384X_RID_ENTSECFLAGEYID 0xFCB9 /* ? */
115#define HFA384X_RID_CNFPASSIVESCANCTRL 0xFCBA /* added in STA f/w 1.5.0 */
116#define HFA384X_RID_SSNHANDLINGMODE 0xFCBB /* added in STA f/w 1.7.0 */
117#define HFA384X_RID_MDCCONTROL 0xFCBC /* added in STA f/w 1.7.0 */
118#define HFA384X_RID_MDCCOUNTRY 0xFCBD /* added in STA f/w 1.7.0 */
119#define HFA384X_RID_TXPOWERMAX 0xFCBE /* added in STA f/w 1.7.0 */
120#define HFA384X_RID_CNFLFOENABLED 0xFCBF /* added in STA f/w 1.6.3 */
121#define HFA384X_RID_CAPINFO 0xFCC0 /* added in STA f/w 1.7.0 */
122#define HFA384X_RID_LISTENINTERVAL 0xFCC1 /* added in STA f/w 1.7.0 */
123#define HFA384X_RID_SW_ANT_DIV 0xFCC2 /* added in STA f/w 1.7.0; Prism3 */
124#define HFA384X_RID_LED_CTRL 0xFCC4 /* added in STA f/w 1.7.6 */
125#define HFA384X_RID_HFODELAY 0xFCC5 /* added in STA f/w 1.7.6 */
126#define HFA384X_RID_DISALLOWEDBSSID 0xFCC6 /* added in STA f/w 1.8.0 */
127#define HFA384X_RID_TICKTIME 0xFCE0
128#define HFA384X_RID_SCANREQUEST 0xFCE1
129#define HFA384X_RID_JOINREQUEST 0xFCE2
130#define HFA384X_RID_AUTHENTICATESTATION 0xFCE3 /* AP f/w only */
131#define HFA384X_RID_CHANNELINFOREQUEST 0xFCE4 /* AP f/w only */
132#define HFA384X_RID_HOSTSCAN 0xFCE5 /* added in STA f/w 1.3.1 */
133
134/* HFA384X Information RIDs */
135#define HFA384X_RID_MAXLOADTIME 0xFD00
136#define HFA384X_RID_DOWNLOADBUFFER 0xFD01
137#define HFA384X_RID_PRIID 0xFD02
138#define HFA384X_RID_PRISUPRANGE 0xFD03
139#define HFA384X_RID_CFIACTRANGES 0xFD04
140#define HFA384X_RID_NICSERNUM 0xFD0A
141#define HFA384X_RID_NICID 0xFD0B
142#define HFA384X_RID_MFISUPRANGE 0xFD0C
143#define HFA384X_RID_CFISUPRANGE 0xFD0D
144#define HFA384X_RID_CHANNELLIST 0xFD10
145#define HFA384X_RID_REGULATORYDOMAINS 0xFD11
146#define HFA384X_RID_TEMPTYPE 0xFD12
147#define HFA384X_RID_CIS 0xFD13
148#define HFA384X_RID_STAID 0xFD20
149#define HFA384X_RID_STASUPRANGE 0xFD21
150#define HFA384X_RID_MFIACTRANGES 0xFD22
151#define HFA384X_RID_CFIACTRANGES2 0xFD23
152#define HFA384X_RID_PRODUCTNAME 0xFD24 /* added in STA f/w 1.3.1;
153 * only Prism2.5(?) */
154#define HFA384X_RID_PORTSTATUS 0xFD40
155#define HFA384X_RID_CURRENTSSID 0xFD41
156#define HFA384X_RID_CURRENTBSSID 0xFD42
157#define HFA384X_RID_COMMSQUALITY 0xFD43
158#define HFA384X_RID_CURRENTTXRATE 0xFD44
159#define HFA384X_RID_CURRENTBEACONINTERVAL 0xFD45
160#define HFA384X_RID_CURRENTSCALETHRESHOLDS 0xFD46
161#define HFA384X_RID_PROTOCOLRSPTIME 0xFD47
162#define HFA384X_RID_SHORTRETRYLIMIT 0xFD48
163#define HFA384X_RID_LONGRETRYLIMIT 0xFD49
164#define HFA384X_RID_MAXTRANSMITLIFETIME 0xFD4A
165#define HFA384X_RID_MAXRECEIVELIFETIME 0xFD4B
166#define HFA384X_RID_CFPOLLABLE 0xFD4C
167#define HFA384X_RID_AUTHENTICATIONALGORITHMS 0xFD4D
168#define HFA384X_RID_PRIVACYOPTIONIMPLEMENTED 0xFD4F
169#define HFA384X_RID_DBMCOMMSQUALITY 0xFD51 /* added in STA f/w 1.3.1 */
170#define HFA384X_RID_CURRENTTXRATE1 0xFD80 /* AP f/w only */
171#define HFA384X_RID_CURRENTTXRATE2 0xFD81 /* AP f/w only */
172#define HFA384X_RID_CURRENTTXRATE3 0xFD82 /* AP f/w only */
173#define HFA384X_RID_CURRENTTXRATE4 0xFD83 /* AP f/w only */
174#define HFA384X_RID_CURRENTTXRATE5 0xFD84 /* AP f/w only */
175#define HFA384X_RID_CURRENTTXRATE6 0xFD85 /* AP f/w only */
176#define HFA384X_RID_OWNMACADDR 0xFD86 /* AP f/w only */
177#define HFA384X_RID_SCANRESULTSTABLE 0xFD88 /* added in STA f/w 0.8.3 */
178#define HFA384X_RID_HOSTSCANRESULTS 0xFD89 /* added in STA f/w 1.3.1 */
179#define HFA384X_RID_AUTHENTICATIONUSED 0xFD8A /* added in STA f/w 1.3.4 */
180#define HFA384X_RID_CNFFAASWITCHCTRL 0xFD8B /* added in STA f/w 1.6.3 */
181#define HFA384X_RID_ASSOCIATIONFAILURE 0xFD8D /* added in STA f/w 1.8.0 */
182#define HFA384X_RID_PHYTYPE 0xFDC0
183#define HFA384X_RID_CURRENTCHANNEL 0xFDC1
184#define HFA384X_RID_CURRENTPOWERSTATE 0xFDC2
185#define HFA384X_RID_CCAMODE 0xFDC3
186#define HFA384X_RID_SUPPORTEDDATARATES 0xFDC6
187#define HFA384X_RID_LFO_VOLT_REG_TEST_RES 0xFDC7 /* added in STA f/w 1.7.1 */
188#define HFA384X_RID_BUILDSEQ 0xFFFE
189#define HFA384X_RID_FWID 0xFFFF
190
191
192struct hfa384x_comp_ident
193{
194 u16 id;
195 u16 variant;
196 u16 major;
197 u16 minor;
198} __attribute__ ((packed));
199
200#define HFA384X_COMP_ID_PRI 0x15
201#define HFA384X_COMP_ID_STA 0x1f
202#define HFA384X_COMP_ID_FW_AP 0x14b
203
204struct hfa384x_sup_range
205{
206 u16 role;
207 u16 id;
208 u16 variant;
209 u16 bottom;
210 u16 top;
211} __attribute__ ((packed));
212
213
214struct hfa384x_build_id
215{
216 u16 pri_seq;
217 u16 sec_seq;
218} __attribute__ ((packed));
219
220/* FD01 - Download Buffer */
221struct hfa384x_rid_download_buffer
222{
223 u16 page;
224 u16 offset;
225 u16 length;
226} __attribute__ ((packed));
227
228/* BSS connection quality (RID FD43 range, RID FD51 dBm-normalized) */
229struct hfa384x_comms_quality {
230 u16 comm_qual; /* 0 .. 92 */
231 u16 signal_level; /* 27 .. 154 */
232 u16 noise_level; /* 27 .. 154 */
233} __attribute__ ((packed));
234
235
236/* netdevice private ioctls (used, e.g., with iwpriv from user space) */
237
238/* New wireless extensions API - SET/GET convention (even ioctl numbers are
239 * root only)
240 */
241#define PRISM2_IOCTL_PRISM2_PARAM (SIOCIWFIRSTPRIV + 0)
242#define PRISM2_IOCTL_GET_PRISM2_PARAM (SIOCIWFIRSTPRIV + 1)
243#define PRISM2_IOCTL_WRITEMIF (SIOCIWFIRSTPRIV + 2)
244#define PRISM2_IOCTL_READMIF (SIOCIWFIRSTPRIV + 3)
245#define PRISM2_IOCTL_MONITOR (SIOCIWFIRSTPRIV + 4)
246#define PRISM2_IOCTL_RESET (SIOCIWFIRSTPRIV + 6)
247#define PRISM2_IOCTL_INQUIRE (SIOCIWFIRSTPRIV + 8)
248#define PRISM2_IOCTL_WDS_ADD (SIOCIWFIRSTPRIV + 10)
249#define PRISM2_IOCTL_WDS_DEL (SIOCIWFIRSTPRIV + 12)
250#define PRISM2_IOCTL_SET_RID_WORD (SIOCIWFIRSTPRIV + 14)
251#define PRISM2_IOCTL_MACCMD (SIOCIWFIRSTPRIV + 16)
252#define PRISM2_IOCTL_ADDMAC (SIOCIWFIRSTPRIV + 18)
253#define PRISM2_IOCTL_DELMAC (SIOCIWFIRSTPRIV + 20)
254#define PRISM2_IOCTL_KICKMAC (SIOCIWFIRSTPRIV + 22)
255
256/* following are not in SIOCGIWPRIV list; check permission in the driver code
257 */
258#define PRISM2_IOCTL_DOWNLOAD (SIOCDEVPRIVATE + 13)
259#define PRISM2_IOCTL_HOSTAPD (SIOCDEVPRIVATE + 14)
260
261
262/* PRISM2_IOCTL_PRISM2_PARAM ioctl() subtypes: */
263enum {
264 /* PRISM2_PARAM_PTYPE = 1, */ /* REMOVED 2003-10-22 */
265 PRISM2_PARAM_TXRATECTRL = 2,
266 PRISM2_PARAM_BEACON_INT = 3,
267 PRISM2_PARAM_PSEUDO_IBSS = 4,
268 PRISM2_PARAM_ALC = 5,
269 /* PRISM2_PARAM_TXPOWER = 6, */ /* REMOVED 2003-10-22 */
270 PRISM2_PARAM_DUMP = 7,
271 PRISM2_PARAM_OTHER_AP_POLICY = 8,
272 PRISM2_PARAM_AP_MAX_INACTIVITY = 9,
273 PRISM2_PARAM_AP_BRIDGE_PACKETS = 10,
274 PRISM2_PARAM_DTIM_PERIOD = 11,
275 PRISM2_PARAM_AP_NULLFUNC_ACK = 12,
276 PRISM2_PARAM_MAX_WDS = 13,
277 PRISM2_PARAM_AP_AUTOM_AP_WDS = 14,
278 PRISM2_PARAM_AP_AUTH_ALGS = 15,
279 PRISM2_PARAM_MONITOR_ALLOW_FCSERR = 16,
280 PRISM2_PARAM_HOST_ENCRYPT = 17,
281 PRISM2_PARAM_HOST_DECRYPT = 18,
282 /* PRISM2_PARAM_BUS_MASTER_THRESHOLD_RX = 19, REMOVED 2005-08-14 */
283 /* PRISM2_PARAM_BUS_MASTER_THRESHOLD_TX = 20, REMOVED 2005-08-14 */
284 PRISM2_PARAM_HOST_ROAMING = 21,
285 PRISM2_PARAM_BCRX_STA_KEY = 22,
286 PRISM2_PARAM_IEEE_802_1X = 23,
287 PRISM2_PARAM_ANTSEL_TX = 24,
288 PRISM2_PARAM_ANTSEL_RX = 25,
289 PRISM2_PARAM_MONITOR_TYPE = 26,
290 PRISM2_PARAM_WDS_TYPE = 27,
291 PRISM2_PARAM_HOSTSCAN = 28,
292 PRISM2_PARAM_AP_SCAN = 29,
293 PRISM2_PARAM_ENH_SEC = 30,
294 PRISM2_PARAM_IO_DEBUG = 31,
295 PRISM2_PARAM_BASIC_RATES = 32,
296 PRISM2_PARAM_OPER_RATES = 33,
297 PRISM2_PARAM_HOSTAPD = 34,
298 PRISM2_PARAM_HOSTAPD_STA = 35,
299 PRISM2_PARAM_WPA = 36,
300 PRISM2_PARAM_PRIVACY_INVOKED = 37,
301 PRISM2_PARAM_TKIP_COUNTERMEASURES = 38,
302 PRISM2_PARAM_DROP_UNENCRYPTED = 39,
303 PRISM2_PARAM_SCAN_CHANNEL_MASK = 40,
304};
305
306enum { HOSTAP_ANTSEL_DO_NOT_TOUCH = 0, HOSTAP_ANTSEL_DIVERSITY = 1,
307 HOSTAP_ANTSEL_LOW = 2, HOSTAP_ANTSEL_HIGH = 3 };
308
309
310/* PRISM2_IOCTL_MACCMD ioctl() subcommands: */
311enum { AP_MAC_CMD_POLICY_OPEN = 0, AP_MAC_CMD_POLICY_ALLOW = 1,
312 AP_MAC_CMD_POLICY_DENY = 2, AP_MAC_CMD_FLUSH = 3,
313 AP_MAC_CMD_KICKALL = 4 };
314
315
316/* PRISM2_IOCTL_DOWNLOAD ioctl() dl_cmd: */
317enum {
318 PRISM2_DOWNLOAD_VOLATILE = 1 /* RAM */,
319 /* Note! Old versions of prism2_srec have a fatal error in CRC-16
320 * calculation, which will corrupt all non-volatile downloads.
321 * PRISM2_DOWNLOAD_NON_VOLATILE used to be 2, but it is now 3 to
322 * prevent use of old versions of prism2_srec for non-volatile
323 * download. */
324 PRISM2_DOWNLOAD_NON_VOLATILE = 3 /* FLASH */,
325 PRISM2_DOWNLOAD_VOLATILE_GENESIS = 4 /* RAM in Genesis mode */,
326 /* Persistent versions of volatile download commands (keep firmware
327 * data in memory and automatically re-download after hw_reset */
328 PRISM2_DOWNLOAD_VOLATILE_PERSISTENT = 5,
329 PRISM2_DOWNLOAD_VOLATILE_GENESIS_PERSISTENT = 6,
330};
331
332struct prism2_download_param {
333 u32 dl_cmd;
334 u32 start_addr;
335 u32 num_areas;
336 struct prism2_download_area {
337 u32 addr; /* wlan card address */
338 u32 len;
339 void __user *ptr; /* pointer to data in user space */
340 } data[0];
341};
342
343#define PRISM2_MAX_DOWNLOAD_AREA_LEN 131072
344#define PRISM2_MAX_DOWNLOAD_LEN 262144
345
346
347/* PRISM2_IOCTL_HOSTAPD ioctl() cmd: */
348enum {
349 PRISM2_HOSTAPD_FLUSH = 1,
350 PRISM2_HOSTAPD_ADD_STA = 2,
351 PRISM2_HOSTAPD_REMOVE_STA = 3,
352 PRISM2_HOSTAPD_GET_INFO_STA = 4,
353 /* REMOVED: PRISM2_HOSTAPD_RESET_TXEXC_STA = 5, */
354 PRISM2_SET_ENCRYPTION = 6,
355 PRISM2_GET_ENCRYPTION = 7,
356 PRISM2_HOSTAPD_SET_FLAGS_STA = 8,
357 PRISM2_HOSTAPD_GET_RID = 9,
358 PRISM2_HOSTAPD_SET_RID = 10,
359 PRISM2_HOSTAPD_SET_ASSOC_AP_ADDR = 11,
360 PRISM2_HOSTAPD_SET_GENERIC_ELEMENT = 12,
361 PRISM2_HOSTAPD_MLME = 13,
362 PRISM2_HOSTAPD_SCAN_REQ = 14,
363 PRISM2_HOSTAPD_STA_CLEAR_STATS = 15,
364};
365
366#define PRISM2_HOSTAPD_MAX_BUF_SIZE 1024
367#define PRISM2_HOSTAPD_RID_HDR_LEN \
368((int) (&((struct prism2_hostapd_param *) 0)->u.rid.data))
369#define PRISM2_HOSTAPD_GENERIC_ELEMENT_HDR_LEN \
370((int) (&((struct prism2_hostapd_param *) 0)->u.generic_elem.data))
371
372/* Maximum length for algorithm names (-1 for nul termination) used in ioctl()
373 */
374#define HOSTAP_CRYPT_ALG_NAME_LEN 16
375
376
377struct prism2_hostapd_param {
378 u32 cmd;
379 u8 sta_addr[ETH_ALEN];
380 union {
381 struct {
382 u16 aid;
383 u16 capability;
384 u8 tx_supp_rates;
385 } add_sta;
386 struct {
387 u32 inactive_sec;
388 } get_info_sta;
389 struct {
390 u8 alg[HOSTAP_CRYPT_ALG_NAME_LEN];
391 u32 flags;
392 u32 err;
393 u8 idx;
394 u8 seq[8]; /* sequence counter (set: RX, get: TX) */
395 u16 key_len;
396 u8 key[0];
397 } crypt;
398 struct {
399 u32 flags_and;
400 u32 flags_or;
401 } set_flags_sta;
402 struct {
403 u16 rid;
404 u16 len;
405 u8 data[0];
406 } rid;
407 struct {
408 u8 len;
409 u8 data[0];
410 } generic_elem;
411 struct {
412#define MLME_STA_DEAUTH 0
413#define MLME_STA_DISASSOC 1
414 u16 cmd;
415 u16 reason_code;
416 } mlme;
417 struct {
418 u8 ssid_len;
419 u8 ssid[32];
420 } scan_req;
421 } u;
422};
423
424#define HOSTAP_CRYPT_FLAG_SET_TX_KEY BIT(0)
425#define HOSTAP_CRYPT_FLAG_PERMANENT BIT(1)
426
427#define HOSTAP_CRYPT_ERR_UNKNOWN_ALG 2
428#define HOSTAP_CRYPT_ERR_UNKNOWN_ADDR 3
429#define HOSTAP_CRYPT_ERR_CRYPT_INIT_FAILED 4
430#define HOSTAP_CRYPT_ERR_KEY_SET_FAILED 5
431#define HOSTAP_CRYPT_ERR_TX_KEY_SET_FAILED 6
432#define HOSTAP_CRYPT_ERR_CARD_CONF_FAILED 7
433
434
435#endif /* HOSTAP_COMMON_H */
diff --git a/drivers/net/wireless/hostap/hostap_config.h b/drivers/net/wireless/hostap/hostap_config.h
new file mode 100644
index 000000000000..7ed3425d08c1
--- /dev/null
+++ b/drivers/net/wireless/hostap/hostap_config.h
@@ -0,0 +1,55 @@
1#ifndef HOSTAP_CONFIG_H
2#define HOSTAP_CONFIG_H
3
4#define PRISM2_VERSION "0.4.4-kernel"
5
6/* In the previous versions of Host AP driver, support for user space version
7 * of IEEE 802.11 management (hostapd) used to be disabled in the default
8 * configuration. From now on, support for hostapd is always included and it is
9 * possible to disable kernel driver version of IEEE 802.11 management with a
10 * separate define, PRISM2_NO_KERNEL_IEEE80211_MGMT. */
11/* #define PRISM2_NO_KERNEL_IEEE80211_MGMT */
12
13/* Maximum number of events handler per one interrupt */
14#define PRISM2_MAX_INTERRUPT_EVENTS 20
15
16/* Include code for downloading firmware images into volatile RAM. */
17#define PRISM2_DOWNLOAD_SUPPORT
18
19/* Allow kernel configuration to enable download support. */
20#if !defined(PRISM2_DOWNLOAD_SUPPORT) && defined(CONFIG_HOSTAP_FIRMWARE)
21#define PRISM2_DOWNLOAD_SUPPORT
22#endif
23
24#ifdef PRISM2_DOWNLOAD_SUPPORT
25/* Allow writing firmware images into flash, i.e., to non-volatile storage.
26 * Before you enable this option, you should make absolutely sure that you are
27 * using prism2_srec utility that comes with THIS version of the driver!
28 * In addition, please note that it is possible to kill your card with
29 * non-volatile download if you are using incorrect image. This feature has not
30 * been fully tested, so please be careful with it. */
31/* #define PRISM2_NON_VOLATILE_DOWNLOAD */
32#endif /* PRISM2_DOWNLOAD_SUPPORT */
33
34/* Save low-level I/O for debugging. This should not be enabled in normal use.
35 */
36/* #define PRISM2_IO_DEBUG */
37
38/* Following defines can be used to remove unneeded parts of the driver, e.g.,
39 * to limit the size of the kernel module. Definitions can be added here in
40 * hostap_config.h or they can be added to make command with EXTRA_CFLAGS,
41 * e.g.,
42 * 'make pccard EXTRA_CFLAGS="-DPRISM2_NO_DEBUG -DPRISM2_NO_PROCFS_DEBUG"'
43 */
44
45/* Do not include debug messages into the driver */
46/* #define PRISM2_NO_DEBUG */
47
48/* Do not include /proc/net/prism2/wlan#/{registers,debug} */
49/* #define PRISM2_NO_PROCFS_DEBUG */
50
51/* Do not include station functionality (i.e., allow only Master (Host AP) mode
52 */
53/* #define PRISM2_NO_STATION_MODES */
54
55#endif /* HOSTAP_CONFIG_H */
diff --git a/drivers/net/wireless/hostap/hostap_cs.c b/drivers/net/wireless/hostap/hostap_cs.c
new file mode 100644
index 000000000000..faa83badf0a1
--- /dev/null
+++ b/drivers/net/wireless/hostap/hostap_cs.c
@@ -0,0 +1,1030 @@
1#define PRISM2_PCCARD
2
3#include <linux/config.h>
4#include <linux/module.h>
5#include <linux/init.h>
6#include <linux/if.h>
7#include <linux/wait.h>
8#include <linux/timer.h>
9#include <linux/skbuff.h>
10#include <linux/netdevice.h>
11#include <linux/workqueue.h>
12#include <linux/wireless.h>
13#include <net/iw_handler.h>
14
15#include <pcmcia/cs_types.h>
16#include <pcmcia/cs.h>
17#include <pcmcia/cistpl.h>
18#include <pcmcia/cisreg.h>
19#include <pcmcia/ds.h>
20
21#include <asm/io.h>
22
23#include "hostap_wlan.h"
24
25
26static char *version = PRISM2_VERSION " (Jouni Malinen <jkmaline@cc.hut.fi>)";
27static dev_info_t dev_info = "hostap_cs";
28static dev_link_t *dev_list = NULL;
29
30MODULE_AUTHOR("Jouni Malinen");
31MODULE_DESCRIPTION("Support for Intersil Prism2-based 802.11 wireless LAN "
32 "cards (PC Card).");
33MODULE_SUPPORTED_DEVICE("Intersil Prism2-based WLAN cards (PC Card)");
34MODULE_LICENSE("GPL");
35MODULE_VERSION(PRISM2_VERSION);
36
37
38static int ignore_cis_vcc;
39module_param(ignore_cis_vcc, int, 0444);
40MODULE_PARM_DESC(ignore_cis_vcc, "Ignore broken CIS VCC entry");
41
42
43/* struct local_info::hw_priv */
44struct hostap_cs_priv {
45 dev_node_t node;
46 dev_link_t *link;
47 int sandisk_connectplus;
48};
49
50
51#ifdef PRISM2_IO_DEBUG
52
53static inline void hfa384x_outb_debug(struct net_device *dev, int a, u8 v)
54{
55 struct hostap_interface *iface;
56 local_info_t *local;
57 unsigned long flags;
58
59 iface = netdev_priv(dev);
60 local = iface->local;
61 spin_lock_irqsave(&local->lock, flags);
62 prism2_io_debug_add(dev, PRISM2_IO_DEBUG_CMD_OUTB, a, v);
63 outb(v, dev->base_addr + a);
64 spin_unlock_irqrestore(&local->lock, flags);
65}
66
67static inline u8 hfa384x_inb_debug(struct net_device *dev, int a)
68{
69 struct hostap_interface *iface;
70 local_info_t *local;
71 unsigned long flags;
72 u8 v;
73
74 iface = netdev_priv(dev);
75 local = iface->local;
76 spin_lock_irqsave(&local->lock, flags);
77 v = inb(dev->base_addr + a);
78 prism2_io_debug_add(dev, PRISM2_IO_DEBUG_CMD_INB, a, v);
79 spin_unlock_irqrestore(&local->lock, flags);
80 return v;
81}
82
83static inline void hfa384x_outw_debug(struct net_device *dev, int a, u16 v)
84{
85 struct hostap_interface *iface;
86 local_info_t *local;
87 unsigned long flags;
88
89 iface = netdev_priv(dev);
90 local = iface->local;
91 spin_lock_irqsave(&local->lock, flags);
92 prism2_io_debug_add(dev, PRISM2_IO_DEBUG_CMD_OUTW, a, v);
93 outw(v, dev->base_addr + a);
94 spin_unlock_irqrestore(&local->lock, flags);
95}
96
97static inline u16 hfa384x_inw_debug(struct net_device *dev, int a)
98{
99 struct hostap_interface *iface;
100 local_info_t *local;
101 unsigned long flags;
102 u16 v;
103
104 iface = netdev_priv(dev);
105 local = iface->local;
106 spin_lock_irqsave(&local->lock, flags);
107 v = inw(dev->base_addr + a);
108 prism2_io_debug_add(dev, PRISM2_IO_DEBUG_CMD_INW, a, v);
109 spin_unlock_irqrestore(&local->lock, flags);
110 return v;
111}
112
113static inline void hfa384x_outsw_debug(struct net_device *dev, int a,
114 u8 *buf, int wc)
115{
116 struct hostap_interface *iface;
117 local_info_t *local;
118 unsigned long flags;
119
120 iface = netdev_priv(dev);
121 local = iface->local;
122 spin_lock_irqsave(&local->lock, flags);
123 prism2_io_debug_add(dev, PRISM2_IO_DEBUG_CMD_OUTSW, a, wc);
124 outsw(dev->base_addr + a, buf, wc);
125 spin_unlock_irqrestore(&local->lock, flags);
126}
127
128static inline void hfa384x_insw_debug(struct net_device *dev, int a,
129 u8 *buf, int wc)
130{
131 struct hostap_interface *iface;
132 local_info_t *local;
133 unsigned long flags;
134
135 iface = netdev_priv(dev);
136 local = iface->local;
137 spin_lock_irqsave(&local->lock, flags);
138 prism2_io_debug_add(dev, PRISM2_IO_DEBUG_CMD_INSW, a, wc);
139 insw(dev->base_addr + a, buf, wc);
140 spin_unlock_irqrestore(&local->lock, flags);
141}
142
143#define HFA384X_OUTB(v,a) hfa384x_outb_debug(dev, (a), (v))
144#define HFA384X_INB(a) hfa384x_inb_debug(dev, (a))
145#define HFA384X_OUTW(v,a) hfa384x_outw_debug(dev, (a), (v))
146#define HFA384X_INW(a) hfa384x_inw_debug(dev, (a))
147#define HFA384X_OUTSW(a, buf, wc) hfa384x_outsw_debug(dev, (a), (buf), (wc))
148#define HFA384X_INSW(a, buf, wc) hfa384x_insw_debug(dev, (a), (buf), (wc))
149
150#else /* PRISM2_IO_DEBUG */
151
152#define HFA384X_OUTB(v,a) outb((v), dev->base_addr + (a))
153#define HFA384X_INB(a) inb(dev->base_addr + (a))
154#define HFA384X_OUTW(v,a) outw((v), dev->base_addr + (a))
155#define HFA384X_INW(a) inw(dev->base_addr + (a))
156#define HFA384X_INSW(a, buf, wc) insw(dev->base_addr + (a), buf, wc)
157#define HFA384X_OUTSW(a, buf, wc) outsw(dev->base_addr + (a), buf, wc)
158
159#endif /* PRISM2_IO_DEBUG */
160
161
162static int hfa384x_from_bap(struct net_device *dev, u16 bap, void *buf,
163 int len)
164{
165 u16 d_off;
166 u16 *pos;
167
168 d_off = (bap == 1) ? HFA384X_DATA1_OFF : HFA384X_DATA0_OFF;
169 pos = (u16 *) buf;
170
171 if (len / 2)
172 HFA384X_INSW(d_off, buf, len / 2);
173 pos += len / 2;
174
175 if (len & 1)
176 *((char *) pos) = HFA384X_INB(d_off);
177
178 return 0;
179}
180
181
182static int hfa384x_to_bap(struct net_device *dev, u16 bap, void *buf, int len)
183{
184 u16 d_off;
185 u16 *pos;
186
187 d_off = (bap == 1) ? HFA384X_DATA1_OFF : HFA384X_DATA0_OFF;
188 pos = (u16 *) buf;
189
190 if (len / 2)
191 HFA384X_OUTSW(d_off, buf, len / 2);
192 pos += len / 2;
193
194 if (len & 1)
195 HFA384X_OUTB(*((char *) pos), d_off);
196
197 return 0;
198}
199
200
201/* FIX: This might change at some point.. */
202#include "hostap_hw.c"
203
204
205
206static void prism2_detach(dev_link_t *link);
207static void prism2_release(u_long arg);
208static int prism2_event(event_t event, int priority,
209 event_callback_args_t *args);
210
211
212static int prism2_pccard_card_present(local_info_t *local)
213{
214 struct hostap_cs_priv *hw_priv = local->hw_priv;
215 if (hw_priv != NULL && hw_priv->link != NULL &&
216 ((hw_priv->link->state & (DEV_PRESENT | DEV_CONFIG)) ==
217 (DEV_PRESENT | DEV_CONFIG)))
218 return 1;
219 return 0;
220}
221
222
223/*
224 * SanDisk CompactFlash WLAN Flashcard - Product Manual v1.0
225 * Document No. 20-10-00058, January 2004
226 * http://www.sandisk.com/pdf/industrial/ProdManualCFWLANv1.0.pdf
227 */
228#define SANDISK_WLAN_ACTIVATION_OFF 0x40
229#define SANDISK_HCR_OFF 0x42
230
231
232static void sandisk_set_iobase(local_info_t *local)
233{
234 int res;
235 conf_reg_t reg;
236 struct hostap_cs_priv *hw_priv = local->hw_priv;
237
238 reg.Function = 0;
239 reg.Action = CS_WRITE;
240 reg.Offset = 0x10; /* 0x3f0 IO base 1 */
241 reg.Value = hw_priv->link->io.BasePort1 & 0x00ff;
242 res = pcmcia_access_configuration_register(hw_priv->link->handle,
243 &reg);
244 if (res != CS_SUCCESS) {
245 printk(KERN_DEBUG "Prism3 SanDisk - failed to set I/O base 0 -"
246 " res=%d\n", res);
247 }
248 udelay(10);
249
250 reg.Function = 0;
251 reg.Action = CS_WRITE;
252 reg.Offset = 0x12; /* 0x3f2 IO base 2 */
253 reg.Value = (hw_priv->link->io.BasePort1 & 0xff00) >> 8;
254 res = pcmcia_access_configuration_register(hw_priv->link->handle,
255 &reg);
256 if (res != CS_SUCCESS) {
257 printk(KERN_DEBUG "Prism3 SanDisk - failed to set I/O base 1 -"
258 " res=%d\n", res);
259 }
260}
261
262
263static void sandisk_write_hcr(local_info_t *local, int hcr)
264{
265 struct net_device *dev = local->dev;
266 int i;
267
268 HFA384X_OUTB(0x80, SANDISK_WLAN_ACTIVATION_OFF);
269 udelay(50);
270 for (i = 0; i < 10; i++) {
271 HFA384X_OUTB(hcr, SANDISK_HCR_OFF);
272 }
273 udelay(55);
274 HFA384X_OUTB(0x45, SANDISK_WLAN_ACTIVATION_OFF);
275}
276
277
278static int sandisk_enable_wireless(struct net_device *dev)
279{
280 int res, ret = 0;
281 conf_reg_t reg;
282 struct hostap_interface *iface = dev->priv;
283 local_info_t *local = iface->local;
284 tuple_t tuple;
285 cisparse_t *parse = NULL;
286 u_char buf[64];
287 struct hostap_cs_priv *hw_priv = local->hw_priv;
288
289 if (hw_priv->link->io.NumPorts1 < 0x42) {
290 /* Not enough ports to be SanDisk multi-function card */
291 ret = -ENODEV;
292 goto done;
293 }
294
295 parse = kmalloc(sizeof(cisparse_t), GFP_KERNEL);
296 if (parse == NULL) {
297 ret = -ENOMEM;
298 goto done;
299 }
300
301 tuple.DesiredTuple = CISTPL_MANFID;
302 tuple.Attributes = TUPLE_RETURN_COMMON;
303 tuple.TupleData = buf;
304 tuple.TupleDataMax = sizeof(buf);
305 tuple.TupleOffset = 0;
306 if (pcmcia_get_first_tuple(hw_priv->link->handle, &tuple) ||
307 pcmcia_get_tuple_data(hw_priv->link->handle, &tuple) ||
308 pcmcia_parse_tuple(hw_priv->link->handle, &tuple, parse) ||
309 parse->manfid.manf != 0xd601 || parse->manfid.card != 0x0101) {
310 /* No SanDisk manfid found */
311 ret = -ENODEV;
312 goto done;
313 }
314
315 tuple.DesiredTuple = CISTPL_LONGLINK_MFC;
316 if (pcmcia_get_first_tuple(hw_priv->link->handle, &tuple) ||
317 pcmcia_get_tuple_data(hw_priv->link->handle, &tuple) ||
318 pcmcia_parse_tuple(hw_priv->link->handle, &tuple, parse) ||
319 parse->longlink_mfc.nfn < 2) {
320 /* No multi-function links found */
321 ret = -ENODEV;
322 goto done;
323 }
324
325 printk(KERN_DEBUG "%s: Multi-function SanDisk ConnectPlus detected"
326 " - using vendor-specific initialization\n", dev->name);
327 hw_priv->sandisk_connectplus = 1;
328
329 reg.Function = 0;
330 reg.Action = CS_WRITE;
331 reg.Offset = CISREG_COR;
332 reg.Value = COR_SOFT_RESET;
333 res = pcmcia_access_configuration_register(hw_priv->link->handle,
334 &reg);
335 if (res != CS_SUCCESS) {
336 printk(KERN_DEBUG "%s: SanDisk - COR sreset failed (%d)\n",
337 dev->name, res);
338 goto done;
339 }
340 mdelay(5);
341
342 reg.Function = 0;
343 reg.Action = CS_WRITE;
344 reg.Offset = CISREG_COR;
345 /*
346 * Do not enable interrupts here to avoid some bogus events. Interrupts
347 * will be enabled during the first cor_sreset call.
348 */
349 reg.Value = COR_LEVEL_REQ | 0x8 | COR_ADDR_DECODE | COR_FUNC_ENA;
350 res = pcmcia_access_configuration_register(hw_priv->link->handle,
351 &reg);
352 if (res != CS_SUCCESS) {
353 printk(KERN_DEBUG "%s: SanDisk - COR sreset failed (%d)\n",
354 dev->name, res);
355 goto done;
356 }
357 mdelay(5);
358
359 sandisk_set_iobase(local);
360
361 HFA384X_OUTB(0xc5, SANDISK_WLAN_ACTIVATION_OFF);
362 udelay(10);
363 HFA384X_OUTB(0x4b, SANDISK_WLAN_ACTIVATION_OFF);
364 udelay(10);
365
366done:
367 kfree(parse);
368 return ret;
369}
370
371
372static void prism2_pccard_cor_sreset(local_info_t *local)
373{
374 int res;
375 conf_reg_t reg;
376 struct hostap_cs_priv *hw_priv = local->hw_priv;
377
378 if (!prism2_pccard_card_present(local))
379 return;
380
381 reg.Function = 0;
382 reg.Action = CS_READ;
383 reg.Offset = CISREG_COR;
384 reg.Value = 0;
385 res = pcmcia_access_configuration_register(hw_priv->link->handle,
386 &reg);
387 if (res != CS_SUCCESS) {
388 printk(KERN_DEBUG "prism2_pccard_cor_sreset failed 1 (%d)\n",
389 res);
390 return;
391 }
392 printk(KERN_DEBUG "prism2_pccard_cor_sreset: original COR %02x\n",
393 reg.Value);
394
395 reg.Action = CS_WRITE;
396 reg.Value |= COR_SOFT_RESET;
397 res = pcmcia_access_configuration_register(hw_priv->link->handle,
398 &reg);
399 if (res != CS_SUCCESS) {
400 printk(KERN_DEBUG "prism2_pccard_cor_sreset failed 2 (%d)\n",
401 res);
402 return;
403 }
404
405 mdelay(hw_priv->sandisk_connectplus ? 5 : 2);
406
407 reg.Value &= ~COR_SOFT_RESET;
408 if (hw_priv->sandisk_connectplus)
409 reg.Value |= COR_IREQ_ENA;
410 res = pcmcia_access_configuration_register(hw_priv->link->handle,
411 &reg);
412 if (res != CS_SUCCESS) {
413 printk(KERN_DEBUG "prism2_pccard_cor_sreset failed 3 (%d)\n",
414 res);
415 return;
416 }
417
418 mdelay(hw_priv->sandisk_connectplus ? 5 : 2);
419
420 if (hw_priv->sandisk_connectplus)
421 sandisk_set_iobase(local);
422}
423
424
425static void prism2_pccard_genesis_reset(local_info_t *local, int hcr)
426{
427 int res;
428 conf_reg_t reg;
429 int old_cor;
430 struct hostap_cs_priv *hw_priv = local->hw_priv;
431
432 if (!prism2_pccard_card_present(local))
433 return;
434
435 if (hw_priv->sandisk_connectplus) {
436 sandisk_write_hcr(local, hcr);
437 return;
438 }
439
440 reg.Function = 0;
441 reg.Action = CS_READ;
442 reg.Offset = CISREG_COR;
443 reg.Value = 0;
444 res = pcmcia_access_configuration_register(hw_priv->link->handle,
445 &reg);
446 if (res != CS_SUCCESS) {
447 printk(KERN_DEBUG "prism2_pccard_genesis_sreset failed 1 "
448 "(%d)\n", res);
449 return;
450 }
451 printk(KERN_DEBUG "prism2_pccard_genesis_sreset: original COR %02x\n",
452 reg.Value);
453 old_cor = reg.Value;
454
455 reg.Action = CS_WRITE;
456 reg.Value |= COR_SOFT_RESET;
457 res = pcmcia_access_configuration_register(hw_priv->link->handle,
458 &reg);
459 if (res != CS_SUCCESS) {
460 printk(KERN_DEBUG "prism2_pccard_genesis_sreset failed 2 "
461 "(%d)\n", res);
462 return;
463 }
464
465 mdelay(10);
466
467 /* Setup Genesis mode */
468 reg.Action = CS_WRITE;
469 reg.Value = hcr;
470 reg.Offset = CISREG_CCSR;
471 res = pcmcia_access_configuration_register(hw_priv->link->handle,
472 &reg);
473 if (res != CS_SUCCESS) {
474 printk(KERN_DEBUG "prism2_pccard_genesis_sreset failed 3 "
475 "(%d)\n", res);
476 return;
477 }
478 mdelay(10);
479
480 reg.Action = CS_WRITE;
481 reg.Offset = CISREG_COR;
482 reg.Value = old_cor & ~COR_SOFT_RESET;
483 res = pcmcia_access_configuration_register(hw_priv->link->handle,
484 &reg);
485 if (res != CS_SUCCESS) {
486 printk(KERN_DEBUG "prism2_pccard_genesis_sreset failed 4 "
487 "(%d)\n", res);
488 return;
489 }
490
491 mdelay(10);
492}
493
494
495static int prism2_pccard_dev_open(local_info_t *local)
496{
497 struct hostap_cs_priv *hw_priv = local->hw_priv;
498 hw_priv->link->open++;
499 return 0;
500}
501
502
503static int prism2_pccard_dev_close(local_info_t *local)
504{
505 struct hostap_cs_priv *hw_priv;
506
507 if (local == NULL || local->hw_priv == NULL)
508 return 1;
509 hw_priv = local->hw_priv;
510 if (hw_priv->link == NULL)
511 return 1;
512
513 if (!hw_priv->link->open) {
514 printk(KERN_WARNING "%s: prism2_pccard_dev_close(): "
515 "link not open?!\n", local->dev->name);
516 return 1;
517 }
518
519 hw_priv->link->open--;
520
521 return 0;
522}
523
524
525static struct prism2_helper_functions prism2_pccard_funcs =
526{
527 .card_present = prism2_pccard_card_present,
528 .cor_sreset = prism2_pccard_cor_sreset,
529 .dev_open = prism2_pccard_dev_open,
530 .dev_close = prism2_pccard_dev_close,
531 .genesis_reset = prism2_pccard_genesis_reset,
532 .hw_type = HOSTAP_HW_PCCARD,
533};
534
535
536/* allocate local data and register with CardServices
537 * initialize dev_link structure, but do not configure the card yet */
538static dev_link_t *prism2_attach(void)
539{
540 dev_link_t *link;
541 client_reg_t client_reg;
542 int ret;
543
544 link = kmalloc(sizeof(dev_link_t), GFP_KERNEL);
545 if (link == NULL)
546 return NULL;
547
548 memset(link, 0, sizeof(dev_link_t));
549
550 PDEBUG(DEBUG_HW, "%s: setting Vcc=33 (constant)\n", dev_info);
551 link->conf.Vcc = 33;
552 link->conf.IntType = INT_MEMORY_AND_IO;
553
554 /* register with CardServices */
555 link->next = dev_list;
556 dev_list = link;
557 client_reg.dev_info = &dev_info;
558 client_reg.Version = 0x0210;
559 client_reg.event_callback_args.client_data = link;
560 ret = pcmcia_register_client(&link->handle, &client_reg);
561 if (ret != CS_SUCCESS) {
562 cs_error(link->handle, RegisterClient, ret);
563 prism2_detach(link);
564 return NULL;
565 }
566 return link;
567}
568
569
570static void prism2_detach(dev_link_t *link)
571{
572 dev_link_t **linkp;
573
574 PDEBUG(DEBUG_FLOW, "prism2_detach\n");
575
576 for (linkp = &dev_list; *linkp; linkp = &(*linkp)->next)
577 if (*linkp == link)
578 break;
579 if (*linkp == NULL) {
580 printk(KERN_WARNING "%s: Attempt to detach non-existing "
581 "PCMCIA client\n", dev_info);
582 return;
583 }
584
585 if (link->state & DEV_CONFIG) {
586 prism2_release((u_long)link);
587 }
588
589 if (link->handle) {
590 int res = pcmcia_deregister_client(link->handle);
591 if (res) {
592 printk("CardService(DeregisterClient) => %d\n", res);
593 cs_error(link->handle, DeregisterClient, res);
594 }
595 }
596
597 *linkp = link->next;
598 /* release net devices */
599 if (link->priv) {
600 struct net_device *dev;
601 struct hostap_interface *iface;
602 dev = link->priv;
603 iface = netdev_priv(dev);
604 kfree(iface->local->hw_priv);
605 iface->local->hw_priv = NULL;
606 prism2_free_local_data(dev);
607 }
608 kfree(link);
609}
610
611
612#define CS_CHECK(fn, ret) \
613do { last_fn = (fn); if ((last_ret = (ret)) != 0) goto cs_failed; } while (0)
614
615#define CFG_CHECK2(fn, retf) \
616do { int ret = (retf); \
617if (ret != 0) { \
618 PDEBUG(DEBUG_EXTRA, "CardServices(" #fn ") returned %d\n", ret); \
619 cs_error(link->handle, fn, ret); \
620 goto next_entry; \
621} \
622} while (0)
623
624
625/* run after a CARD_INSERTION event is received to configure the PCMCIA
626 * socket and make the device available to the system */
627static int prism2_config(dev_link_t *link)
628{
629 struct net_device *dev;
630 struct hostap_interface *iface;
631 local_info_t *local;
632 int ret = 1;
633 tuple_t tuple;
634 cisparse_t *parse;
635 int last_fn, last_ret;
636 u_char buf[64];
637 config_info_t conf;
638 cistpl_cftable_entry_t dflt = { 0 };
639 struct hostap_cs_priv *hw_priv;
640
641 PDEBUG(DEBUG_FLOW, "prism2_config()\n");
642
643 parse = kmalloc(sizeof(cisparse_t), GFP_KERNEL);
644 hw_priv = kmalloc(sizeof(*hw_priv), GFP_KERNEL);
645 if (parse == NULL || hw_priv == NULL) {
646 kfree(parse);
647 kfree(hw_priv);
648 ret = -ENOMEM;
649 goto failed;
650 }
651 memset(hw_priv, 0, sizeof(*hw_priv));
652
653 tuple.DesiredTuple = CISTPL_CONFIG;
654 tuple.Attributes = 0;
655 tuple.TupleData = buf;
656 tuple.TupleDataMax = sizeof(buf);
657 tuple.TupleOffset = 0;
658 CS_CHECK(GetFirstTuple, pcmcia_get_first_tuple(link->handle, &tuple));
659 CS_CHECK(GetTupleData, pcmcia_get_tuple_data(link->handle, &tuple));
660 CS_CHECK(ParseTuple, pcmcia_parse_tuple(link->handle, &tuple, parse));
661 link->conf.ConfigBase = parse->config.base;
662 link->conf.Present = parse->config.rmask[0];
663
664 CS_CHECK(GetConfigurationInfo,
665 pcmcia_get_configuration_info(link->handle, &conf));
666 PDEBUG(DEBUG_HW, "%s: %s Vcc=%d (from config)\n", dev_info,
667 ignore_cis_vcc ? "ignoring" : "setting", conf.Vcc);
668 link->conf.Vcc = conf.Vcc;
669
670 /* Look for an appropriate configuration table entry in the CIS */
671 tuple.DesiredTuple = CISTPL_CFTABLE_ENTRY;
672 CS_CHECK(GetFirstTuple, pcmcia_get_first_tuple(link->handle, &tuple));
673 for (;;) {
674 cistpl_cftable_entry_t *cfg = &(parse->cftable_entry);
675 CFG_CHECK2(GetTupleData,
676 pcmcia_get_tuple_data(link->handle, &tuple));
677 CFG_CHECK2(ParseTuple,
678 pcmcia_parse_tuple(link->handle, &tuple, parse));
679
680 if (cfg->flags & CISTPL_CFTABLE_DEFAULT)
681 dflt = *cfg;
682 if (cfg->index == 0)
683 goto next_entry;
684 link->conf.ConfigIndex = cfg->index;
685 PDEBUG(DEBUG_EXTRA, "Checking CFTABLE_ENTRY 0x%02X "
686 "(default 0x%02X)\n", cfg->index, dflt.index);
687
688 /* Does this card need audio output? */
689 if (cfg->flags & CISTPL_CFTABLE_AUDIO) {
690 link->conf.Attributes |= CONF_ENABLE_SPKR;
691 link->conf.Status = CCSR_AUDIO_ENA;
692 }
693
694 /* Use power settings for Vcc and Vpp if present */
695 /* Note that the CIS values need to be rescaled */
696 if (cfg->vcc.present & (1 << CISTPL_POWER_VNOM)) {
697 if (conf.Vcc != cfg->vcc.param[CISTPL_POWER_VNOM] /
698 10000 && !ignore_cis_vcc) {
699 PDEBUG(DEBUG_EXTRA, " Vcc mismatch - skipping"
700 " this entry\n");
701 goto next_entry;
702 }
703 } else if (dflt.vcc.present & (1 << CISTPL_POWER_VNOM)) {
704 if (conf.Vcc != dflt.vcc.param[CISTPL_POWER_VNOM] /
705 10000 && !ignore_cis_vcc) {
706 PDEBUG(DEBUG_EXTRA, " Vcc (default) mismatch "
707 "- skipping this entry\n");
708 goto next_entry;
709 }
710 }
711
712 if (cfg->vpp1.present & (1 << CISTPL_POWER_VNOM))
713 link->conf.Vpp1 = link->conf.Vpp2 =
714 cfg->vpp1.param[CISTPL_POWER_VNOM] / 10000;
715 else if (dflt.vpp1.present & (1 << CISTPL_POWER_VNOM))
716 link->conf.Vpp1 = link->conf.Vpp2 =
717 dflt.vpp1.param[CISTPL_POWER_VNOM] / 10000;
718
719 /* Do we need to allocate an interrupt? */
720 if (cfg->irq.IRQInfo1 || dflt.irq.IRQInfo1)
721 link->conf.Attributes |= CONF_ENABLE_IRQ;
722 else if (!(link->conf.Attributes & CONF_ENABLE_IRQ)) {
723 /* At least Compaq WL200 does not have IRQInfo1 set,
724 * but it does not work without interrupts.. */
725 printk("Config has no IRQ info, but trying to enable "
726 "IRQ anyway..\n");
727 link->conf.Attributes |= CONF_ENABLE_IRQ;
728 }
729
730 /* IO window settings */
731 PDEBUG(DEBUG_EXTRA, "IO window settings: cfg->io.nwin=%d "
732 "dflt.io.nwin=%d\n",
733 cfg->io.nwin, dflt.io.nwin);
734 link->io.NumPorts1 = link->io.NumPorts2 = 0;
735 if ((cfg->io.nwin > 0) || (dflt.io.nwin > 0)) {
736 cistpl_io_t *io = (cfg->io.nwin) ? &cfg->io : &dflt.io;
737 link->io.Attributes1 = IO_DATA_PATH_WIDTH_AUTO;
738 PDEBUG(DEBUG_EXTRA, "io->flags = 0x%04X, "
739 "io.base=0x%04x, len=%d\n", io->flags,
740 io->win[0].base, io->win[0].len);
741 if (!(io->flags & CISTPL_IO_8BIT))
742 link->io.Attributes1 = IO_DATA_PATH_WIDTH_16;
743 if (!(io->flags & CISTPL_IO_16BIT))
744 link->io.Attributes1 = IO_DATA_PATH_WIDTH_8;
745 link->io.IOAddrLines = io->flags &
746 CISTPL_IO_LINES_MASK;
747 link->io.BasePort1 = io->win[0].base;
748 link->io.NumPorts1 = io->win[0].len;
749 if (io->nwin > 1) {
750 link->io.Attributes2 = link->io.Attributes1;
751 link->io.BasePort2 = io->win[1].base;
752 link->io.NumPorts2 = io->win[1].len;
753 }
754 }
755
756 /* This reserves IO space but doesn't actually enable it */
757 CFG_CHECK2(RequestIO,
758 pcmcia_request_io(link->handle, &link->io));
759
760 /* This configuration table entry is OK */
761 break;
762
763 next_entry:
764 CS_CHECK(GetNextTuple,
765 pcmcia_get_next_tuple(link->handle, &tuple));
766 }
767
768 /* Need to allocate net_device before requesting IRQ handler */
769 dev = prism2_init_local_data(&prism2_pccard_funcs, 0,
770 &handle_to_dev(link->handle));
771 if (dev == NULL)
772 goto failed;
773 link->priv = dev;
774
775 iface = netdev_priv(dev);
776 local = iface->local;
777 local->hw_priv = hw_priv;
778 hw_priv->link = link;
779 strcpy(hw_priv->node.dev_name, dev->name);
780 link->dev = &hw_priv->node;
781
782 /*
783 * Allocate an interrupt line. Note that this does not assign a
784 * handler to the interrupt, unless the 'Handler' member of the
785 * irq structure is initialized.
786 */
787 if (link->conf.Attributes & CONF_ENABLE_IRQ) {
788 link->irq.Attributes = IRQ_TYPE_EXCLUSIVE | IRQ_HANDLE_PRESENT;
789 link->irq.IRQInfo1 = IRQ_LEVEL_ID;
790 link->irq.Handler = prism2_interrupt;
791 link->irq.Instance = dev;
792 CS_CHECK(RequestIRQ,
793 pcmcia_request_irq(link->handle, &link->irq));
794 }
795
796 /*
797 * This actually configures the PCMCIA socket -- setting up
798 * the I/O windows and the interrupt mapping, and putting the
799 * card and host interface into "Memory and IO" mode.
800 */
801 CS_CHECK(RequestConfiguration,
802 pcmcia_request_configuration(link->handle, &link->conf));
803
804 dev->irq = link->irq.AssignedIRQ;
805 dev->base_addr = link->io.BasePort1;
806
807 /* Finally, report what we've done */
808 printk(KERN_INFO "%s: index 0x%02x: Vcc %d.%d",
809 dev_info, link->conf.ConfigIndex,
810 link->conf.Vcc / 10, link->conf.Vcc % 10);
811 if (link->conf.Vpp1)
812 printk(", Vpp %d.%d", link->conf.Vpp1 / 10,
813 link->conf.Vpp1 % 10);
814 if (link->conf.Attributes & CONF_ENABLE_IRQ)
815 printk(", irq %d", link->irq.AssignedIRQ);
816 if (link->io.NumPorts1)
817 printk(", io 0x%04x-0x%04x", link->io.BasePort1,
818 link->io.BasePort1+link->io.NumPorts1-1);
819 if (link->io.NumPorts2)
820 printk(" & 0x%04x-0x%04x", link->io.BasePort2,
821 link->io.BasePort2+link->io.NumPorts2-1);
822 printk("\n");
823
824 link->state |= DEV_CONFIG;
825 link->state &= ~DEV_CONFIG_PENDING;
826
827 local->shutdown = 0;
828
829 sandisk_enable_wireless(dev);
830
831 ret = prism2_hw_config(dev, 1);
832 if (!ret) {
833 ret = hostap_hw_ready(dev);
834 if (ret == 0 && local->ddev)
835 strcpy(hw_priv->node.dev_name, local->ddev->name);
836 }
837 kfree(parse);
838 return ret;
839
840 cs_failed:
841 cs_error(link->handle, last_fn, last_ret);
842
843 failed:
844 kfree(parse);
845 kfree(hw_priv);
846 prism2_release((u_long)link);
847 return ret;
848}
849
850
851static void prism2_release(u_long arg)
852{
853 dev_link_t *link = (dev_link_t *)arg;
854
855 PDEBUG(DEBUG_FLOW, "prism2_release\n");
856
857 if (link->priv) {
858 struct net_device *dev = link->priv;
859 struct hostap_interface *iface;
860
861 iface = netdev_priv(dev);
862 if (link->state & DEV_CONFIG)
863 prism2_hw_shutdown(dev, 0);
864 iface->local->shutdown = 1;
865 }
866
867 if (link->win)
868 pcmcia_release_window(link->win);
869 pcmcia_release_configuration(link->handle);
870 if (link->io.NumPorts1)
871 pcmcia_release_io(link->handle, &link->io);
872 if (link->irq.AssignedIRQ)
873 pcmcia_release_irq(link->handle, &link->irq);
874
875 link->state &= ~DEV_CONFIG;
876
877 PDEBUG(DEBUG_FLOW, "release - done\n");
878}
879
880
881static int prism2_event(event_t event, int priority,
882 event_callback_args_t *args)
883{
884 dev_link_t *link = args->client_data;
885 struct net_device *dev = (struct net_device *) link->priv;
886
887 switch (event) {
888 case CS_EVENT_CARD_INSERTION:
889 PDEBUG(DEBUG_EXTRA, "%s: CS_EVENT_CARD_INSERTION\n", dev_info);
890 link->state |= DEV_PRESENT | DEV_CONFIG_PENDING;
891 if (prism2_config(link)) {
892 PDEBUG(DEBUG_EXTRA, "prism2_config() failed\n");
893 }
894 break;
895
896 case CS_EVENT_CARD_REMOVAL:
897 PDEBUG(DEBUG_EXTRA, "%s: CS_EVENT_CARD_REMOVAL\n", dev_info);
898 link->state &= ~DEV_PRESENT;
899 if (link->state & DEV_CONFIG) {
900 netif_stop_queue(dev);
901 netif_device_detach(dev);
902 prism2_release((u_long) link);
903 }
904 break;
905
906 case CS_EVENT_PM_SUSPEND:
907 PDEBUG(DEBUG_EXTRA, "%s: CS_EVENT_PM_SUSPEND\n", dev_info);
908 link->state |= DEV_SUSPEND;
909 /* fall through */
910
911 case CS_EVENT_RESET_PHYSICAL:
912 PDEBUG(DEBUG_EXTRA, "%s: CS_EVENT_RESET_PHYSICAL\n", dev_info);
913 if (link->state & DEV_CONFIG) {
914 if (link->open) {
915 netif_stop_queue(dev);
916 netif_device_detach(dev);
917 }
918 prism2_suspend(dev);
919 pcmcia_release_configuration(link->handle);
920 }
921 break;
922
923 case CS_EVENT_PM_RESUME:
924 PDEBUG(DEBUG_EXTRA, "%s: CS_EVENT_PM_RESUME\n", dev_info);
925 link->state &= ~DEV_SUSPEND;
926 /* fall through */
927
928 case CS_EVENT_CARD_RESET:
929 PDEBUG(DEBUG_EXTRA, "%s: CS_EVENT_CARD_RESET\n", dev_info);
930 if (link->state & DEV_CONFIG) {
931 pcmcia_request_configuration(link->handle,
932 &link->conf);
933 prism2_hw_shutdown(dev, 1);
934 prism2_hw_config(dev, link->open ? 0 : 1);
935 if (link->open) {
936 netif_device_attach(dev);
937 netif_start_queue(dev);
938 }
939 }
940 break;
941
942 default:
943 PDEBUG(DEBUG_EXTRA, "%s: prism2_event() - unknown event %d\n",
944 dev_info, event);
945 break;
946 }
947 return 0;
948}
949
950
951static struct pcmcia_device_id hostap_cs_ids[] = {
952 PCMCIA_DEVICE_MANF_CARD(0x000b, 0x7100),
953 PCMCIA_DEVICE_MANF_CARD(0x000b, 0x7300),
954 PCMCIA_DEVICE_MANF_CARD(0x0101, 0x0777),
955 PCMCIA_DEVICE_MANF_CARD(0x0126, 0x8000),
956 PCMCIA_DEVICE_MANF_CARD(0x0138, 0x0002),
957 PCMCIA_DEVICE_MANF_CARD(0x0156, 0x0002),
958 PCMCIA_DEVICE_MANF_CARD(0x0250, 0x0002),
959 PCMCIA_DEVICE_MANF_CARD(0x026f, 0x030b),
960 PCMCIA_DEVICE_MANF_CARD(0x0274, 0x1612),
961 PCMCIA_DEVICE_MANF_CARD(0x0274, 0x1613),
962 PCMCIA_DEVICE_MANF_CARD(0x028a, 0x0002),
963 PCMCIA_DEVICE_MANF_CARD(0x02aa, 0x0002),
964 PCMCIA_DEVICE_MANF_CARD(0x02d2, 0x0001),
965 PCMCIA_DEVICE_MANF_CARD(0x50c2, 0x0001),
966 PCMCIA_DEVICE_MANF_CARD(0x50c2, 0x7300),
967 PCMCIA_DEVICE_MANF_CARD(0xc00f, 0x0000),
968 PCMCIA_DEVICE_MANF_CARD(0xd601, 0x0002),
969 PCMCIA_DEVICE_MANF_CARD(0xd601, 0x0005),
970 PCMCIA_DEVICE_MANF_CARD(0xd601, 0x0010),
971 PCMCIA_MFC_DEVICE_PROD_ID12(0, "SanDisk", "ConnectPlus",
972 0x7a954bd9, 0x74be00c6),
973 PCMCIA_DEVICE_PROD_ID1234(
974 "Intersil", "PRISM 2_5 PCMCIA ADAPTER", "ISL37300P",
975 "Eval-RevA",
976 0x4b801a17, 0x6345a0bf, 0xc9049a39, 0xc23adc0e),
977 PCMCIA_DEVICE_PROD_ID123(
978 "Addtron", "AWP-100 Wireless PCMCIA", "Version 01.02",
979 0xe6ec52ce, 0x08649af2, 0x4b74baa0),
980 PCMCIA_DEVICE_PROD_ID123(
981 "D", "Link DWL-650 11Mbps WLAN Card", "Version 01.02",
982 0x71b18589, 0xb6f1b0ab, 0x4b74baa0),
983 PCMCIA_DEVICE_PROD_ID123(
984 "Instant Wireless ", " Network PC CARD", "Version 01.02",
985 0x11d901af, 0x6e9bd926, 0x4b74baa0),
986 PCMCIA_DEVICE_PROD_ID123(
987 "SMC", "SMC2632W", "Version 01.02",
988 0xc4f8b18b, 0x474a1f2a, 0x4b74baa0),
989 PCMCIA_DEVICE_PROD_ID12("BUFFALO", "WLI-CF-S11G",
990 0x2decece3, 0x82067c18),
991 PCMCIA_DEVICE_PROD_ID12("Compaq", "WL200_11Mbps_Wireless_PCI_Card",
992 0x54f7c49c, 0x15a75e5b),
993 PCMCIA_DEVICE_PROD_ID12("INTERSIL", "HFA384x/IEEE",
994 0x74c5e40d, 0xdb472a18),
995 PCMCIA_DEVICE_PROD_ID12("Linksys", "Wireless CompactFlash Card",
996 0x0733cc81, 0x0c52f395),
997 PCMCIA_DEVICE_PROD_ID12(
998 "ZoomAir 11Mbps High", "Rate wireless Networking",
999 0x273fe3db, 0x32a1eaee),
1000 PCMCIA_DEVICE_NULL
1001};
1002MODULE_DEVICE_TABLE(pcmcia, hostap_cs_ids);
1003
1004
1005static struct pcmcia_driver hostap_driver = {
1006 .drv = {
1007 .name = "hostap_cs",
1008 },
1009 .attach = prism2_attach,
1010 .detach = prism2_detach,
1011 .owner = THIS_MODULE,
1012 .event = prism2_event,
1013 .id_table = hostap_cs_ids,
1014};
1015
1016static int __init init_prism2_pccard(void)
1017{
1018 printk(KERN_INFO "%s: %s\n", dev_info, version);
1019 return pcmcia_register_driver(&hostap_driver);
1020}
1021
1022static void __exit exit_prism2_pccard(void)
1023{
1024 pcmcia_unregister_driver(&hostap_driver);
1025 printk(KERN_INFO "%s: Driver unloaded\n", dev_info);
1026}
1027
1028
1029module_init(init_prism2_pccard);
1030module_exit(exit_prism2_pccard);
diff --git a/drivers/net/wireless/hostap/hostap_download.c b/drivers/net/wireless/hostap/hostap_download.c
new file mode 100644
index 000000000000..ab26b52b3e76
--- /dev/null
+++ b/drivers/net/wireless/hostap/hostap_download.c
@@ -0,0 +1,766 @@
1static int prism2_enable_aux_port(struct net_device *dev, int enable)
2{
3 u16 val, reg;
4 int i, tries;
5 unsigned long flags;
6 struct hostap_interface *iface;
7 local_info_t *local;
8
9 iface = netdev_priv(dev);
10 local = iface->local;
11
12 if (local->no_pri) {
13 if (enable) {
14 PDEBUG(DEBUG_EXTRA2, "%s: no PRI f/w - assuming Aux "
15 "port is already enabled\n", dev->name);
16 }
17 return 0;
18 }
19
20 spin_lock_irqsave(&local->cmdlock, flags);
21
22 /* wait until busy bit is clear */
23 tries = HFA384X_CMD_BUSY_TIMEOUT;
24 while (HFA384X_INW(HFA384X_CMD_OFF) & HFA384X_CMD_BUSY && tries > 0) {
25 tries--;
26 udelay(1);
27 }
28 if (tries == 0) {
29 reg = HFA384X_INW(HFA384X_CMD_OFF);
30 spin_unlock_irqrestore(&local->cmdlock, flags);
31 printk("%s: prism2_enable_aux_port - timeout - reg=0x%04x\n",
32 dev->name, reg);
33 return -ETIMEDOUT;
34 }
35
36 val = HFA384X_INW(HFA384X_CONTROL_OFF);
37
38 if (enable) {
39 HFA384X_OUTW(HFA384X_AUX_MAGIC0, HFA384X_PARAM0_OFF);
40 HFA384X_OUTW(HFA384X_AUX_MAGIC1, HFA384X_PARAM1_OFF);
41 HFA384X_OUTW(HFA384X_AUX_MAGIC2, HFA384X_PARAM2_OFF);
42
43 if ((val & HFA384X_AUX_PORT_MASK) != HFA384X_AUX_PORT_DISABLED)
44 printk("prism2_enable_aux_port: was not disabled!?\n");
45 val &= ~HFA384X_AUX_PORT_MASK;
46 val |= HFA384X_AUX_PORT_ENABLE;
47 } else {
48 HFA384X_OUTW(0, HFA384X_PARAM0_OFF);
49 HFA384X_OUTW(0, HFA384X_PARAM1_OFF);
50 HFA384X_OUTW(0, HFA384X_PARAM2_OFF);
51
52 if ((val & HFA384X_AUX_PORT_MASK) != HFA384X_AUX_PORT_ENABLED)
53 printk("prism2_enable_aux_port: was not enabled!?\n");
54 val &= ~HFA384X_AUX_PORT_MASK;
55 val |= HFA384X_AUX_PORT_DISABLE;
56 }
57 HFA384X_OUTW(val, HFA384X_CONTROL_OFF);
58
59 udelay(5);
60
61 i = 10000;
62 while (i > 0) {
63 val = HFA384X_INW(HFA384X_CONTROL_OFF);
64 val &= HFA384X_AUX_PORT_MASK;
65
66 if ((enable && val == HFA384X_AUX_PORT_ENABLED) ||
67 (!enable && val == HFA384X_AUX_PORT_DISABLED))
68 break;
69
70 udelay(10);
71 i--;
72 }
73
74 spin_unlock_irqrestore(&local->cmdlock, flags);
75
76 if (i == 0) {
77 printk("prism2_enable_aux_port(%d) timed out\n",
78 enable);
79 return -ETIMEDOUT;
80 }
81
82 return 0;
83}
84
85
86static int hfa384x_from_aux(struct net_device *dev, unsigned int addr, int len,
87 void *buf)
88{
89 u16 page, offset;
90 if (addr & 1 || len & 1)
91 return -1;
92
93 page = addr >> 7;
94 offset = addr & 0x7f;
95
96 HFA384X_OUTW(page, HFA384X_AUXPAGE_OFF);
97 HFA384X_OUTW(offset, HFA384X_AUXOFFSET_OFF);
98
99 udelay(5);
100
101#ifdef PRISM2_PCI
102 {
103 u16 *pos = (u16 *) buf;
104 while (len > 0) {
105 *pos++ = HFA384X_INW_DATA(HFA384X_AUXDATA_OFF);
106 len -= 2;
107 }
108 }
109#else /* PRISM2_PCI */
110 HFA384X_INSW(HFA384X_AUXDATA_OFF, buf, len / 2);
111#endif /* PRISM2_PCI */
112
113 return 0;
114}
115
116
117static int hfa384x_to_aux(struct net_device *dev, unsigned int addr, int len,
118 void *buf)
119{
120 u16 page, offset;
121 if (addr & 1 || len & 1)
122 return -1;
123
124 page = addr >> 7;
125 offset = addr & 0x7f;
126
127 HFA384X_OUTW(page, HFA384X_AUXPAGE_OFF);
128 HFA384X_OUTW(offset, HFA384X_AUXOFFSET_OFF);
129
130 udelay(5);
131
132#ifdef PRISM2_PCI
133 {
134 u16 *pos = (u16 *) buf;
135 while (len > 0) {
136 HFA384X_OUTW_DATA(*pos++, HFA384X_AUXDATA_OFF);
137 len -= 2;
138 }
139 }
140#else /* PRISM2_PCI */
141 HFA384X_OUTSW(HFA384X_AUXDATA_OFF, buf, len / 2);
142#endif /* PRISM2_PCI */
143
144 return 0;
145}
146
147
148static int prism2_pda_ok(u8 *buf)
149{
150 u16 *pda = (u16 *) buf;
151 int pos;
152 u16 len, pdr;
153
154 if (buf[0] == 0xff && buf[1] == 0x00 && buf[2] == 0xff &&
155 buf[3] == 0x00)
156 return 0;
157
158 pos = 0;
159 while (pos + 1 < PRISM2_PDA_SIZE / 2) {
160 len = le16_to_cpu(pda[pos]);
161 pdr = le16_to_cpu(pda[pos + 1]);
162 if (len == 0 || pos + len > PRISM2_PDA_SIZE / 2)
163 return 0;
164
165 if (pdr == 0x0000 && len == 2) {
166 /* PDA end found */
167 return 1;
168 }
169
170 pos += len + 1;
171 }
172
173 return 0;
174}
175
176
177static int prism2_download_aux_dump(struct net_device *dev,
178 unsigned int addr, int len, u8 *buf)
179{
180 int res;
181
182 prism2_enable_aux_port(dev, 1);
183 res = hfa384x_from_aux(dev, addr, len, buf);
184 prism2_enable_aux_port(dev, 0);
185 if (res)
186 return -1;
187
188 return 0;
189}
190
191
192static u8 * prism2_read_pda(struct net_device *dev)
193{
194 u8 *buf;
195 int res, i, found = 0;
196#define NUM_PDA_ADDRS 4
197 unsigned int pda_addr[NUM_PDA_ADDRS] = {
198 0x7f0000 /* others than HFA3841 */,
199 0x3f0000 /* HFA3841 */,
200 0x390000 /* apparently used in older cards */,
201 0x7f0002 /* Intel PRO/Wireless 2011B (PCI) */,
202 };
203
204 buf = (u8 *) kmalloc(PRISM2_PDA_SIZE, GFP_KERNEL);
205 if (buf == NULL)
206 return NULL;
207
208 /* Note: wlan card should be in initial state (just after init cmd)
209 * and no other operations should be performed concurrently. */
210
211 prism2_enable_aux_port(dev, 1);
212
213 for (i = 0; i < NUM_PDA_ADDRS; i++) {
214 PDEBUG(DEBUG_EXTRA2, "%s: trying to read PDA from 0x%08x",
215 dev->name, pda_addr[i]);
216 res = hfa384x_from_aux(dev, pda_addr[i], PRISM2_PDA_SIZE, buf);
217 if (res)
218 continue;
219 if (res == 0 && prism2_pda_ok(buf)) {
220 PDEBUG2(DEBUG_EXTRA2, ": OK\n");
221 found = 1;
222 break;
223 } else {
224 PDEBUG2(DEBUG_EXTRA2, ": failed\n");
225 }
226 }
227
228 prism2_enable_aux_port(dev, 0);
229
230 if (!found) {
231 printk(KERN_DEBUG "%s: valid PDA not found\n", dev->name);
232 kfree(buf);
233 buf = NULL;
234 }
235
236 return buf;
237}
238
239
240static int prism2_download_volatile(local_info_t *local,
241 struct prism2_download_data *param)
242{
243 struct net_device *dev = local->dev;
244 int ret = 0, i;
245 u16 param0, param1;
246
247 if (local->hw_downloading) {
248 printk(KERN_WARNING "%s: Already downloading - aborting new "
249 "request\n", dev->name);
250 return -1;
251 }
252
253 local->hw_downloading = 1;
254 if (local->pri_only) {
255 hfa384x_disable_interrupts(dev);
256 } else {
257 prism2_hw_shutdown(dev, 0);
258
259 if (prism2_hw_init(dev, 0)) {
260 printk(KERN_WARNING "%s: Could not initialize card for"
261 " download\n", dev->name);
262 ret = -1;
263 goto out;
264 }
265 }
266
267 if (prism2_enable_aux_port(dev, 1)) {
268 printk(KERN_WARNING "%s: Could not enable AUX port\n",
269 dev->name);
270 ret = -1;
271 goto out;
272 }
273
274 param0 = param->start_addr & 0xffff;
275 param1 = param->start_addr >> 16;
276
277 HFA384X_OUTW(0, HFA384X_PARAM2_OFF);
278 HFA384X_OUTW(param1, HFA384X_PARAM1_OFF);
279 if (hfa384x_cmd_wait(dev, HFA384X_CMDCODE_DOWNLOAD |
280 (HFA384X_PROGMODE_ENABLE_VOLATILE << 8),
281 param0)) {
282 printk(KERN_WARNING "%s: Download command execution failed\n",
283 dev->name);
284 ret = -1;
285 goto out;
286 }
287
288 for (i = 0; i < param->num_areas; i++) {
289 PDEBUG(DEBUG_EXTRA2, "%s: Writing %d bytes at 0x%08x\n",
290 dev->name, param->data[i].len, param->data[i].addr);
291 if (hfa384x_to_aux(dev, param->data[i].addr,
292 param->data[i].len, param->data[i].data)) {
293 printk(KERN_WARNING "%s: RAM download at 0x%08x "
294 "(len=%d) failed\n", dev->name,
295 param->data[i].addr, param->data[i].len);
296 ret = -1;
297 goto out;
298 }
299 }
300
301 HFA384X_OUTW(param1, HFA384X_PARAM1_OFF);
302 HFA384X_OUTW(0, HFA384X_PARAM2_OFF);
303 if (hfa384x_cmd_no_wait(dev, HFA384X_CMDCODE_DOWNLOAD |
304 (HFA384X_PROGMODE_DISABLE << 8), param0)) {
305 printk(KERN_WARNING "%s: Download command execution failed\n",
306 dev->name);
307 ret = -1;
308 goto out;
309 }
310 /* ProgMode disable causes the hardware to restart itself from the
311 * given starting address. Give hw some time and ACK command just in
312 * case restart did not happen. */
313 mdelay(5);
314 HFA384X_OUTW(HFA384X_EV_CMD, HFA384X_EVACK_OFF);
315
316 if (prism2_enable_aux_port(dev, 0)) {
317 printk(KERN_DEBUG "%s: Disabling AUX port failed\n",
318 dev->name);
319 /* continue anyway.. restart should have taken care of this */
320 }
321
322 mdelay(5);
323 local->hw_downloading = 0;
324 if (prism2_hw_config(dev, 2)) {
325 printk(KERN_WARNING "%s: Card configuration after RAM "
326 "download failed\n", dev->name);
327 ret = -1;
328 goto out;
329 }
330
331 out:
332 local->hw_downloading = 0;
333 return ret;
334}
335
336
337static int prism2_enable_genesis(local_info_t *local, int hcr)
338{
339 struct net_device *dev = local->dev;
340 u8 initseq[4] = { 0x00, 0xe1, 0xa1, 0xff };
341 u8 readbuf[4];
342
343 printk(KERN_DEBUG "%s: test Genesis mode with HCR 0x%02x\n",
344 dev->name, hcr);
345 local->func->cor_sreset(local);
346 hfa384x_to_aux(dev, 0x7e0038, sizeof(initseq), initseq);
347 local->func->genesis_reset(local, hcr);
348
349 /* Readback test */
350 hfa384x_from_aux(dev, 0x7e0038, sizeof(readbuf), readbuf);
351 hfa384x_to_aux(dev, 0x7e0038, sizeof(initseq), initseq);
352 hfa384x_from_aux(dev, 0x7e0038, sizeof(readbuf), readbuf);
353
354 if (memcmp(initseq, readbuf, sizeof(initseq)) == 0) {
355 printk(KERN_DEBUG "Readback test succeeded, HCR 0x%02x\n",
356 hcr);
357 return 0;
358 } else {
359 printk(KERN_DEBUG "Readback test failed, HCR 0x%02x "
360 "write %02x %02x %02x %02x read %02x %02x %02x %02x\n",
361 hcr, initseq[0], initseq[1], initseq[2], initseq[3],
362 readbuf[0], readbuf[1], readbuf[2], readbuf[3]);
363 return 1;
364 }
365}
366
367
368static int prism2_get_ram_size(local_info_t *local)
369{
370 int ret;
371
372 /* Try to enable genesis mode; 0x1F for x8 SRAM or 0x0F for x16 SRAM */
373 if (prism2_enable_genesis(local, 0x1f) == 0)
374 ret = 8;
375 else if (prism2_enable_genesis(local, 0x0f) == 0)
376 ret = 16;
377 else
378 ret = -1;
379
380 /* Disable genesis mode */
381 local->func->genesis_reset(local, ret == 16 ? 0x07 : 0x17);
382
383 return ret;
384}
385
386
387static int prism2_download_genesis(local_info_t *local,
388 struct prism2_download_data *param)
389{
390 struct net_device *dev = local->dev;
391 int ram16 = 0, i;
392 int ret = 0;
393
394 if (local->hw_downloading) {
395 printk(KERN_WARNING "%s: Already downloading - aborting new "
396 "request\n", dev->name);
397 return -EBUSY;
398 }
399
400 if (!local->func->genesis_reset || !local->func->cor_sreset) {
401 printk(KERN_INFO "%s: Genesis mode downloading not supported "
402 "with this hwmodel\n", dev->name);
403 return -EOPNOTSUPP;
404 }
405
406 local->hw_downloading = 1;
407
408 if (prism2_enable_aux_port(dev, 1)) {
409 printk(KERN_DEBUG "%s: failed to enable AUX port\n",
410 dev->name);
411 ret = -EIO;
412 goto out;
413 }
414
415 if (local->sram_type == -1) {
416 /* 0x1F for x8 SRAM or 0x0F for x16 SRAM */
417 if (prism2_enable_genesis(local, 0x1f) == 0) {
418 ram16 = 0;
419 PDEBUG(DEBUG_EXTRA2, "%s: Genesis mode OK using x8 "
420 "SRAM\n", dev->name);
421 } else if (prism2_enable_genesis(local, 0x0f) == 0) {
422 ram16 = 1;
423 PDEBUG(DEBUG_EXTRA2, "%s: Genesis mode OK using x16 "
424 "SRAM\n", dev->name);
425 } else {
426 printk(KERN_DEBUG "%s: Could not initiate genesis "
427 "mode\n", dev->name);
428 ret = -EIO;
429 goto out;
430 }
431 } else {
432 if (prism2_enable_genesis(local, local->sram_type == 8 ?
433 0x1f : 0x0f)) {
434 printk(KERN_DEBUG "%s: Failed to set Genesis "
435 "mode (sram_type=%d)\n", dev->name,
436 local->sram_type);
437 ret = -EIO;
438 goto out;
439 }
440 ram16 = local->sram_type != 8;
441 }
442
443 for (i = 0; i < param->num_areas; i++) {
444 PDEBUG(DEBUG_EXTRA2, "%s: Writing %d bytes at 0x%08x\n",
445 dev->name, param->data[i].len, param->data[i].addr);
446 if (hfa384x_to_aux(dev, param->data[i].addr,
447 param->data[i].len, param->data[i].data)) {
448 printk(KERN_WARNING "%s: RAM download at 0x%08x "
449 "(len=%d) failed\n", dev->name,
450 param->data[i].addr, param->data[i].len);
451 ret = -EIO;
452 goto out;
453 }
454 }
455
456 PDEBUG(DEBUG_EXTRA2, "Disable genesis mode\n");
457 local->func->genesis_reset(local, ram16 ? 0x07 : 0x17);
458 if (prism2_enable_aux_port(dev, 0)) {
459 printk(KERN_DEBUG "%s: Failed to disable AUX port\n",
460 dev->name);
461 }
462
463 mdelay(5);
464 local->hw_downloading = 0;
465
466 PDEBUG(DEBUG_EXTRA2, "Trying to initialize card\n");
467 /*
468 * Make sure the INIT command does not generate a command completion
469 * event by disabling interrupts.
470 */
471 hfa384x_disable_interrupts(dev);
472 if (prism2_hw_init(dev, 1)) {
473 printk(KERN_DEBUG "%s: Initialization after genesis mode "
474 "download failed\n", dev->name);
475 ret = -EIO;
476 goto out;
477 }
478
479 PDEBUG(DEBUG_EXTRA2, "Card initialized - running PRI only\n");
480 if (prism2_hw_init2(dev, 1)) {
481 printk(KERN_DEBUG "%s: Initialization(2) after genesis mode "
482 "download failed\n", dev->name);
483 ret = -EIO;
484 goto out;
485 }
486
487 out:
488 local->hw_downloading = 0;
489 return ret;
490}
491
492
493#ifdef PRISM2_NON_VOLATILE_DOWNLOAD
494/* Note! Non-volatile downloading functionality has not yet been tested
495 * thoroughly and it may corrupt flash image and effectively kill the card that
496 * is being updated. You have been warned. */
497
498static inline int prism2_download_block(struct net_device *dev,
499 u32 addr, u8 *data,
500 u32 bufaddr, int rest_len)
501{
502 u16 param0, param1;
503 int block_len;
504
505 block_len = rest_len < 4096 ? rest_len : 4096;
506
507 param0 = addr & 0xffff;
508 param1 = addr >> 16;
509
510 HFA384X_OUTW(block_len, HFA384X_PARAM2_OFF);
511 HFA384X_OUTW(param1, HFA384X_PARAM1_OFF);
512
513 if (hfa384x_cmd_wait(dev, HFA384X_CMDCODE_DOWNLOAD |
514 (HFA384X_PROGMODE_ENABLE_NON_VOLATILE << 8),
515 param0)) {
516 printk(KERN_WARNING "%s: Flash download command execution "
517 "failed\n", dev->name);
518 return -1;
519 }
520
521 if (hfa384x_to_aux(dev, bufaddr, block_len, data)) {
522 printk(KERN_WARNING "%s: flash download at 0x%08x "
523 "(len=%d) failed\n", dev->name, addr, block_len);
524 return -1;
525 }
526
527 HFA384X_OUTW(0, HFA384X_PARAM2_OFF);
528 HFA384X_OUTW(0, HFA384X_PARAM1_OFF);
529 if (hfa384x_cmd_wait(dev, HFA384X_CMDCODE_DOWNLOAD |
530 (HFA384X_PROGMODE_PROGRAM_NON_VOLATILE << 8),
531 0)) {
532 printk(KERN_WARNING "%s: Flash write command execution "
533 "failed\n", dev->name);
534 return -1;
535 }
536
537 return block_len;
538}
539
540
541static int prism2_download_nonvolatile(local_info_t *local,
542 struct prism2_download_data *dl)
543{
544 struct net_device *dev = local->dev;
545 int ret = 0, i;
546 struct {
547 u16 page;
548 u16 offset;
549 u16 len;
550 } dlbuffer;
551 u32 bufaddr;
552
553 if (local->hw_downloading) {
554 printk(KERN_WARNING "%s: Already downloading - aborting new "
555 "request\n", dev->name);
556 return -1;
557 }
558
559 ret = local->func->get_rid(dev, HFA384X_RID_DOWNLOADBUFFER,
560 &dlbuffer, 6, 0);
561
562 if (ret < 0) {
563 printk(KERN_WARNING "%s: Could not read download buffer "
564 "parameters\n", dev->name);
565 goto out;
566 }
567
568 dlbuffer.page = le16_to_cpu(dlbuffer.page);
569 dlbuffer.offset = le16_to_cpu(dlbuffer.offset);
570 dlbuffer.len = le16_to_cpu(dlbuffer.len);
571
572 printk(KERN_DEBUG "Download buffer: %d bytes at 0x%04x:0x%04x\n",
573 dlbuffer.len, dlbuffer.page, dlbuffer.offset);
574
575 bufaddr = (dlbuffer.page << 7) + dlbuffer.offset;
576
577 local->hw_downloading = 1;
578
579 if (!local->pri_only) {
580 prism2_hw_shutdown(dev, 0);
581
582 if (prism2_hw_init(dev, 0)) {
583 printk(KERN_WARNING "%s: Could not initialize card for"
584 " download\n", dev->name);
585 ret = -1;
586 goto out;
587 }
588 }
589
590 hfa384x_disable_interrupts(dev);
591
592 if (prism2_enable_aux_port(dev, 1)) {
593 printk(KERN_WARNING "%s: Could not enable AUX port\n",
594 dev->name);
595 ret = -1;
596 goto out;
597 }
598
599 printk(KERN_DEBUG "%s: starting flash download\n", dev->name);
600 for (i = 0; i < dl->num_areas; i++) {
601 int rest_len = dl->data[i].len;
602 int data_off = 0;
603
604 while (rest_len > 0) {
605 int block_len;
606
607 block_len = prism2_download_block(
608 dev, dl->data[i].addr + data_off,
609 dl->data[i].data + data_off, bufaddr,
610 rest_len);
611
612 if (block_len < 0) {
613 ret = -1;
614 goto out;
615 }
616
617 rest_len -= block_len;
618 data_off += block_len;
619 }
620 }
621
622 HFA384X_OUTW(0, HFA384X_PARAM1_OFF);
623 HFA384X_OUTW(0, HFA384X_PARAM2_OFF);
624 if (hfa384x_cmd_wait(dev, HFA384X_CMDCODE_DOWNLOAD |
625 (HFA384X_PROGMODE_DISABLE << 8), 0)) {
626 printk(KERN_WARNING "%s: Download command execution failed\n",
627 dev->name);
628 ret = -1;
629 goto out;
630 }
631
632 if (prism2_enable_aux_port(dev, 0)) {
633 printk(KERN_DEBUG "%s: Disabling AUX port failed\n",
634 dev->name);
635 /* continue anyway.. restart should have taken care of this */
636 }
637
638 mdelay(5);
639
640 local->func->hw_reset(dev);
641 local->hw_downloading = 0;
642 if (prism2_hw_config(dev, 2)) {
643 printk(KERN_WARNING "%s: Card configuration after flash "
644 "download failed\n", dev->name);
645 ret = -1;
646 } else {
647 printk(KERN_INFO "%s: Card initialized successfully after "
648 "flash download\n", dev->name);
649 }
650
651 out:
652 local->hw_downloading = 0;
653 return ret;
654}
655#endif /* PRISM2_NON_VOLATILE_DOWNLOAD */
656
657
658static void prism2_download_free_data(struct prism2_download_data *dl)
659{
660 int i;
661
662 if (dl == NULL)
663 return;
664
665 for (i = 0; i < dl->num_areas; i++)
666 kfree(dl->data[i].data);
667 kfree(dl);
668}
669
670
671static int prism2_download(local_info_t *local,
672 struct prism2_download_param *param)
673{
674 int ret = 0;
675 int i;
676 u32 total_len = 0;
677 struct prism2_download_data *dl = NULL;
678
679 printk(KERN_DEBUG "prism2_download: dl_cmd=%d start_addr=0x%08x "
680 "num_areas=%d\n",
681 param->dl_cmd, param->start_addr, param->num_areas);
682
683 if (param->num_areas > 100) {
684 ret = -EINVAL;
685 goto out;
686 }
687
688 dl = kmalloc(sizeof(*dl) + param->num_areas *
689 sizeof(struct prism2_download_data_area), GFP_KERNEL);
690 if (dl == NULL) {
691 ret = -ENOMEM;
692 goto out;
693 }
694 memset(dl, 0, sizeof(*dl) + param->num_areas *
695 sizeof(struct prism2_download_data_area));
696 dl->dl_cmd = param->dl_cmd;
697 dl->start_addr = param->start_addr;
698 dl->num_areas = param->num_areas;
699 for (i = 0; i < param->num_areas; i++) {
700 PDEBUG(DEBUG_EXTRA2,
701 " area %d: addr=0x%08x len=%d ptr=0x%p\n",
702 i, param->data[i].addr, param->data[i].len,
703 param->data[i].ptr);
704
705 dl->data[i].addr = param->data[i].addr;
706 dl->data[i].len = param->data[i].len;
707
708 total_len += param->data[i].len;
709 if (param->data[i].len > PRISM2_MAX_DOWNLOAD_AREA_LEN ||
710 total_len > PRISM2_MAX_DOWNLOAD_LEN) {
711 ret = -E2BIG;
712 goto out;
713 }
714
715 dl->data[i].data = kmalloc(dl->data[i].len, GFP_KERNEL);
716 if (dl->data[i].data == NULL) {
717 ret = -ENOMEM;
718 goto out;
719 }
720
721 if (copy_from_user(dl->data[i].data, param->data[i].ptr,
722 param->data[i].len)) {
723 ret = -EFAULT;
724 goto out;
725 }
726 }
727
728 switch (param->dl_cmd) {
729 case PRISM2_DOWNLOAD_VOLATILE:
730 case PRISM2_DOWNLOAD_VOLATILE_PERSISTENT:
731 ret = prism2_download_volatile(local, dl);
732 break;
733 case PRISM2_DOWNLOAD_VOLATILE_GENESIS:
734 case PRISM2_DOWNLOAD_VOLATILE_GENESIS_PERSISTENT:
735 ret = prism2_download_genesis(local, dl);
736 break;
737 case PRISM2_DOWNLOAD_NON_VOLATILE:
738#ifdef PRISM2_NON_VOLATILE_DOWNLOAD
739 ret = prism2_download_nonvolatile(local, dl);
740#else /* PRISM2_NON_VOLATILE_DOWNLOAD */
741 printk(KERN_INFO "%s: non-volatile downloading not enabled\n",
742 local->dev->name);
743 ret = -EOPNOTSUPP;
744#endif /* PRISM2_NON_VOLATILE_DOWNLOAD */
745 break;
746 default:
747 printk(KERN_DEBUG "%s: unsupported download command %d\n",
748 local->dev->name, param->dl_cmd);
749 ret = -EINVAL;
750 break;
751 };
752
753 out:
754 if (ret == 0 && dl &&
755 param->dl_cmd == PRISM2_DOWNLOAD_VOLATILE_GENESIS_PERSISTENT) {
756 prism2_download_free_data(local->dl_pri);
757 local->dl_pri = dl;
758 } else if (ret == 0 && dl &&
759 param->dl_cmd == PRISM2_DOWNLOAD_VOLATILE_PERSISTENT) {
760 prism2_download_free_data(local->dl_sec);
761 local->dl_sec = dl;
762 } else
763 prism2_download_free_data(dl);
764
765 return ret;
766}
diff --git a/drivers/net/wireless/hostap/hostap_hw.c b/drivers/net/wireless/hostap/hostap_hw.c
new file mode 100644
index 000000000000..e533a663deda
--- /dev/null
+++ b/drivers/net/wireless/hostap/hostap_hw.c
@@ -0,0 +1,3445 @@
1/*
2 * Host AP (software wireless LAN access point) driver for
3 * Intersil Prism2/2.5/3.
4 *
5 * Copyright (c) 2001-2002, SSH Communications Security Corp and Jouni Malinen
6 * <jkmaline@cc.hut.fi>
7 * Copyright (c) 2002-2005, Jouni Malinen <jkmaline@cc.hut.fi>
8 *
9 * This program is free software; you can redistribute it and/or modify
10 * it under the terms of the GNU General Public License version 2 as
11 * published by the Free Software Foundation. See README and COPYING for
12 * more details.
13 *
14 * FIX:
15 * - there is currently no way of associating TX packets to correct wds device
16 * when TX Exc/OK event occurs, so all tx_packets and some
17 * tx_errors/tx_dropped are added to the main netdevice; using sw_support
18 * field in txdesc might be used to fix this (using Alloc event to increment
19 * tx_packets would need some further info in txfid table)
20 *
21 * Buffer Access Path (BAP) usage:
22 * Prism2 cards have two separate BAPs for accessing the card memory. These
23 * should allow concurrent access to two different frames and the driver
24 * previously used BAP0 for sending data and BAP1 for receiving data.
25 * However, there seems to be number of issues with concurrent access and at
26 * least one know hardware bug in using BAP0 and BAP1 concurrently with PCI
27 * Prism2.5. Therefore, the driver now only uses BAP0 for moving data between
28 * host and card memories. BAP0 accesses are protected with local->baplock
29 * (spin_lock_bh) to prevent concurrent use.
30 */
31
32
33#include <linux/config.h>
34#include <linux/version.h>
35
36#include <asm/delay.h>
37#include <asm/uaccess.h>
38
39#include <linux/slab.h>
40#include <linux/netdevice.h>
41#include <linux/etherdevice.h>
42#include <linux/proc_fs.h>
43#include <linux/if_arp.h>
44#include <linux/delay.h>
45#include <linux/random.h>
46#include <linux/wait.h>
47#include <linux/sched.h>
48#include <linux/rtnetlink.h>
49#include <linux/wireless.h>
50#include <net/iw_handler.h>
51#include <net/ieee80211.h>
52#include <net/ieee80211_crypt.h>
53#include <asm/irq.h>
54
55#include "hostap_80211.h"
56#include "hostap.h"
57#include "hostap_ap.h"
58
59
60/* #define final_version */
61
62static int mtu = 1500;
63module_param(mtu, int, 0444);
64MODULE_PARM_DESC(mtu, "Maximum transfer unit");
65
66static int channel[MAX_PARM_DEVICES] = { 3, DEF_INTS };
67module_param_array(channel, int, NULL, 0444);
68MODULE_PARM_DESC(channel, "Initial channel");
69
70static char essid[33] = "test";
71module_param_string(essid, essid, sizeof(essid), 0444);
72MODULE_PARM_DESC(essid, "Host AP's ESSID");
73
74static int iw_mode[MAX_PARM_DEVICES] = { IW_MODE_MASTER, DEF_INTS };
75module_param_array(iw_mode, int, NULL, 0444);
76MODULE_PARM_DESC(iw_mode, "Initial operation mode");
77
78static int beacon_int[MAX_PARM_DEVICES] = { 100, DEF_INTS };
79module_param_array(beacon_int, int, NULL, 0444);
80MODULE_PARM_DESC(beacon_int, "Beacon interval (1 = 1024 usec)");
81
82static int dtim_period[MAX_PARM_DEVICES] = { 1, DEF_INTS };
83module_param_array(dtim_period, int, NULL, 0444);
84MODULE_PARM_DESC(dtim_period, "DTIM period");
85
86static char dev_template[16] = "wlan%d";
87module_param_string(dev_template, dev_template, sizeof(dev_template), 0444);
88MODULE_PARM_DESC(dev_template, "Prefix for network device name (default: "
89 "wlan%d)");
90
91#ifdef final_version
92#define EXTRA_EVENTS_WTERR 0
93#else
94/* check WTERR events (Wait Time-out) in development versions */
95#define EXTRA_EVENTS_WTERR HFA384X_EV_WTERR
96#endif
97
98/* Events that will be using BAP0 */
99#define HFA384X_BAP0_EVENTS \
100 (HFA384X_EV_TXEXC | HFA384X_EV_RX | HFA384X_EV_INFO | HFA384X_EV_TX)
101
102/* event mask, i.e., events that will result in an interrupt */
103#define HFA384X_EVENT_MASK \
104 (HFA384X_BAP0_EVENTS | HFA384X_EV_ALLOC | HFA384X_EV_INFDROP | \
105 HFA384X_EV_CMD | HFA384X_EV_TICK | \
106 EXTRA_EVENTS_WTERR)
107
108/* Default TX control flags: use 802.11 headers and request interrupt for
109 * failed transmits. Frames that request ACK callback, will add
110 * _TX_OK flag and _ALT_RTRY flag may be used to select different retry policy.
111 */
112#define HFA384X_TX_CTRL_FLAGS \
113 (HFA384X_TX_CTRL_802_11 | HFA384X_TX_CTRL_TX_EX)
114
115
116/* ca. 1 usec */
117#define HFA384X_CMD_BUSY_TIMEOUT 5000
118#define HFA384X_BAP_BUSY_TIMEOUT 50000
119
120/* ca. 10 usec */
121#define HFA384X_CMD_COMPL_TIMEOUT 20000
122#define HFA384X_DL_COMPL_TIMEOUT 1000000
123
124/* Wait times for initialization; yield to other processes to avoid busy
125 * waiting for long time. */
126#define HFA384X_INIT_TIMEOUT (HZ / 2) /* 500 ms */
127#define HFA384X_ALLOC_COMPL_TIMEOUT (HZ / 20) /* 50 ms */
128
129
130static void prism2_hw_reset(struct net_device *dev);
131static void prism2_check_sta_fw_version(local_info_t *local);
132
133#ifdef PRISM2_DOWNLOAD_SUPPORT
134/* hostap_download.c */
135static int prism2_download_aux_dump(struct net_device *dev,
136 unsigned int addr, int len, u8 *buf);
137static u8 * prism2_read_pda(struct net_device *dev);
138static int prism2_download(local_info_t *local,
139 struct prism2_download_param *param);
140static void prism2_download_free_data(struct prism2_download_data *dl);
141static int prism2_download_volatile(local_info_t *local,
142 struct prism2_download_data *param);
143static int prism2_download_genesis(local_info_t *local,
144 struct prism2_download_data *param);
145static int prism2_get_ram_size(local_info_t *local);
146#endif /* PRISM2_DOWNLOAD_SUPPORT */
147
148
149
150
151#ifndef final_version
152/* magic value written to SWSUPPORT0 reg. for detecting whether card is still
153 * present */
154#define HFA384X_MAGIC 0x8A32
155#endif
156
157
158static u16 hfa384x_read_reg(struct net_device *dev, u16 reg)
159{
160 return HFA384X_INW(reg);
161}
162
163
164static void hfa384x_read_regs(struct net_device *dev,
165 struct hfa384x_regs *regs)
166{
167 regs->cmd = HFA384X_INW(HFA384X_CMD_OFF);
168 regs->evstat = HFA384X_INW(HFA384X_EVSTAT_OFF);
169 regs->offset0 = HFA384X_INW(HFA384X_OFFSET0_OFF);
170 regs->offset1 = HFA384X_INW(HFA384X_OFFSET1_OFF);
171 regs->swsupport0 = HFA384X_INW(HFA384X_SWSUPPORT0_OFF);
172}
173
174
175/**
176 * __hostap_cmd_queue_free - Free Prism2 command queue entry (private)
177 * @local: pointer to private Host AP driver data
178 * @entry: Prism2 command queue entry to be freed
179 * @del_req: request the entry to be removed
180 *
181 * Internal helper function for freeing Prism2 command queue entries.
182 * Caller must have acquired local->cmdlock before calling this function.
183 */
184static inline void __hostap_cmd_queue_free(local_info_t *local,
185 struct hostap_cmd_queue *entry,
186 int del_req)
187{
188 if (del_req) {
189 entry->del_req = 1;
190 if (!list_empty(&entry->list)) {
191 list_del_init(&entry->list);
192 local->cmd_queue_len--;
193 }
194 }
195
196 if (atomic_dec_and_test(&entry->usecnt) && entry->del_req)
197 kfree(entry);
198}
199
200
201/**
202 * hostap_cmd_queue_free - Free Prism2 command queue entry
203 * @local: pointer to private Host AP driver data
204 * @entry: Prism2 command queue entry to be freed
205 * @del_req: request the entry to be removed
206 *
207 * Free a Prism2 command queue entry.
208 */
209static inline void hostap_cmd_queue_free(local_info_t *local,
210 struct hostap_cmd_queue *entry,
211 int del_req)
212{
213 unsigned long flags;
214
215 spin_lock_irqsave(&local->cmdlock, flags);
216 __hostap_cmd_queue_free(local, entry, del_req);
217 spin_unlock_irqrestore(&local->cmdlock, flags);
218}
219
220
221/**
222 * prism2_clear_cmd_queue - Free all pending Prism2 command queue entries
223 * @local: pointer to private Host AP driver data
224 */
225static void prism2_clear_cmd_queue(local_info_t *local)
226{
227 struct list_head *ptr, *n;
228 unsigned long flags;
229 struct hostap_cmd_queue *entry;
230
231 spin_lock_irqsave(&local->cmdlock, flags);
232 list_for_each_safe(ptr, n, &local->cmd_queue) {
233 entry = list_entry(ptr, struct hostap_cmd_queue, list);
234 atomic_inc(&entry->usecnt);
235 printk(KERN_DEBUG "%s: removed pending cmd_queue entry "
236 "(type=%d, cmd=0x%04x, param0=0x%04x)\n",
237 local->dev->name, entry->type, entry->cmd,
238 entry->param0);
239 __hostap_cmd_queue_free(local, entry, 1);
240 }
241 if (local->cmd_queue_len) {
242 /* This should not happen; print debug message and clear
243 * queue length. */
244 printk(KERN_DEBUG "%s: cmd_queue_len (%d) not zero after "
245 "flush\n", local->dev->name, local->cmd_queue_len);
246 local->cmd_queue_len = 0;
247 }
248 spin_unlock_irqrestore(&local->cmdlock, flags);
249}
250
251
252/**
253 * hfa384x_cmd_issue - Issue a Prism2 command to the hardware
254 * @dev: pointer to net_device
255 * @entry: Prism2 command queue entry to be issued
256 */
257static inline int hfa384x_cmd_issue(struct net_device *dev,
258 struct hostap_cmd_queue *entry)
259{
260 struct hostap_interface *iface;
261 local_info_t *local;
262 int tries;
263 u16 reg;
264 unsigned long flags;
265
266 iface = netdev_priv(dev);
267 local = iface->local;
268
269 if (local->func->card_present && !local->func->card_present(local))
270 return -ENODEV;
271
272 if (entry->issued) {
273 printk(KERN_DEBUG "%s: driver bug - re-issuing command @%p\n",
274 dev->name, entry);
275 }
276
277 /* wait until busy bit is clear; this should always be clear since the
278 * commands are serialized */
279 tries = HFA384X_CMD_BUSY_TIMEOUT;
280 while (HFA384X_INW(HFA384X_CMD_OFF) & HFA384X_CMD_BUSY && tries > 0) {
281 tries--;
282 udelay(1);
283 }
284#ifndef final_version
285 if (tries != HFA384X_CMD_BUSY_TIMEOUT) {
286 prism2_io_debug_error(dev, 1);
287 printk(KERN_DEBUG "%s: hfa384x_cmd_issue: cmd reg was busy "
288 "for %d usec\n", dev->name,
289 HFA384X_CMD_BUSY_TIMEOUT - tries);
290 }
291#endif
292 if (tries == 0) {
293 reg = HFA384X_INW(HFA384X_CMD_OFF);
294 prism2_io_debug_error(dev, 2);
295 printk(KERN_DEBUG "%s: hfa384x_cmd_issue - timeout - "
296 "reg=0x%04x\n", dev->name, reg);
297 return -ETIMEDOUT;
298 }
299
300 /* write command */
301 spin_lock_irqsave(&local->cmdlock, flags);
302 HFA384X_OUTW(entry->param0, HFA384X_PARAM0_OFF);
303 HFA384X_OUTW(entry->param1, HFA384X_PARAM1_OFF);
304 HFA384X_OUTW(entry->cmd, HFA384X_CMD_OFF);
305 entry->issued = 1;
306 spin_unlock_irqrestore(&local->cmdlock, flags);
307
308 return 0;
309}
310
311
312/**
313 * hfa384x_cmd - Issue a Prism2 command and wait (sleep) for completion
314 * @dev: pointer to net_device
315 * @cmd: Prism2 command code (HFA384X_CMD_CODE_*)
316 * @param0: value for Param0 register
317 * @param1: value for Param1 register (pointer; %NULL if not used)
318 * @resp0: pointer for Resp0 data or %NULL if Resp0 is not needed
319 *
320 * Issue given command (possibly after waiting in command queue) and sleep
321 * until the command is completed (or timed out or interrupted). This can be
322 * called only from user process context.
323 */
324static int hfa384x_cmd(struct net_device *dev, u16 cmd, u16 param0,
325 u16 *param1, u16 *resp0)
326{
327 struct hostap_interface *iface;
328 local_info_t *local;
329 int err, res, issue, issued = 0;
330 unsigned long flags;
331 struct hostap_cmd_queue *entry;
332 DECLARE_WAITQUEUE(wait, current);
333
334 iface = netdev_priv(dev);
335 local = iface->local;
336
337 if (in_interrupt()) {
338 printk(KERN_DEBUG "%s: hfa384x_cmd called from interrupt "
339 "context\n", dev->name);
340 return -1;
341 }
342
343 if (local->cmd_queue_len >= HOSTAP_CMD_QUEUE_MAX_LEN) {
344 printk(KERN_DEBUG "%s: hfa384x_cmd: cmd_queue full\n",
345 dev->name);
346 return -1;
347 }
348
349 if (signal_pending(current))
350 return -EINTR;
351
352 entry = (struct hostap_cmd_queue *)
353 kmalloc(sizeof(*entry), GFP_ATOMIC);
354 if (entry == NULL) {
355 printk(KERN_DEBUG "%s: hfa384x_cmd - kmalloc failed\n",
356 dev->name);
357 return -ENOMEM;
358 }
359 memset(entry, 0, sizeof(*entry));
360 atomic_set(&entry->usecnt, 1);
361 entry->type = CMD_SLEEP;
362 entry->cmd = cmd;
363 entry->param0 = param0;
364 if (param1)
365 entry->param1 = *param1;
366 init_waitqueue_head(&entry->compl);
367
368 /* prepare to wait for command completion event, but do not sleep yet
369 */
370 add_wait_queue(&entry->compl, &wait);
371 set_current_state(TASK_INTERRUPTIBLE);
372
373 spin_lock_irqsave(&local->cmdlock, flags);
374 issue = list_empty(&local->cmd_queue);
375 if (issue)
376 entry->issuing = 1;
377 list_add_tail(&entry->list, &local->cmd_queue);
378 local->cmd_queue_len++;
379 spin_unlock_irqrestore(&local->cmdlock, flags);
380
381 err = 0;
382 if (!issue)
383 goto wait_completion;
384
385 if (signal_pending(current))
386 err = -EINTR;
387
388 if (!err) {
389 if (hfa384x_cmd_issue(dev, entry))
390 err = -ETIMEDOUT;
391 else
392 issued = 1;
393 }
394
395 wait_completion:
396 if (!err && entry->type != CMD_COMPLETED) {
397 /* sleep until command is completed or timed out */
398 res = schedule_timeout(2 * HZ);
399 } else
400 res = -1;
401
402 if (!err && signal_pending(current))
403 err = -EINTR;
404
405 if (err && issued) {
406 /* the command was issued, so a CmdCompl event should occur
407 * soon; however, there's a pending signal and
408 * schedule_timeout() would be interrupted; wait a short period
409 * of time to avoid removing entry from the list before
410 * CmdCompl event */
411 udelay(300);
412 }
413
414 set_current_state(TASK_RUNNING);
415 remove_wait_queue(&entry->compl, &wait);
416
417 /* If entry->list is still in the list, it must be removed
418 * first and in this case prism2_cmd_ev() does not yet have
419 * local reference to it, and the data can be kfree()'d
420 * here. If the command completion event is still generated,
421 * it will be assigned to next (possibly) pending command, but
422 * the driver will reset the card anyway due to timeout
423 *
424 * If the entry is not in the list prism2_cmd_ev() has a local
425 * reference to it, but keeps cmdlock as long as the data is
426 * needed, so the data can be kfree()'d here. */
427
428 /* FIX: if the entry->list is in the list, it has not been completed
429 * yet, so removing it here is somewhat wrong.. this could cause
430 * references to freed memory and next list_del() causing NULL pointer
431 * dereference.. it would probably be better to leave the entry in the
432 * list and the list should be emptied during hw reset */
433
434 spin_lock_irqsave(&local->cmdlock, flags);
435 if (!list_empty(&entry->list)) {
436 printk(KERN_DEBUG "%s: hfa384x_cmd: entry still in list? "
437 "(entry=%p, type=%d, res=%d)\n", dev->name, entry,
438 entry->type, res);
439 list_del_init(&entry->list);
440 local->cmd_queue_len--;
441 }
442 spin_unlock_irqrestore(&local->cmdlock, flags);
443
444 if (err) {
445 printk(KERN_DEBUG "%s: hfa384x_cmd: interrupted; err=%d\n",
446 dev->name, err);
447 res = err;
448 goto done;
449 }
450
451 if (entry->type != CMD_COMPLETED) {
452 u16 reg = HFA384X_INW(HFA384X_EVSTAT_OFF);
453 printk(KERN_DEBUG "%s: hfa384x_cmd: command was not "
454 "completed (res=%d, entry=%p, type=%d, cmd=0x%04x, "
455 "param0=0x%04x, EVSTAT=%04x INTEN=%04x)\n", dev->name,
456 res, entry, entry->type, entry->cmd, entry->param0, reg,
457 HFA384X_INW(HFA384X_INTEN_OFF));
458 if (reg & HFA384X_EV_CMD) {
459 /* Command completion event is pending, but the
460 * interrupt was not delivered - probably an issue
461 * with pcmcia-cs configuration. */
462 printk(KERN_WARNING "%s: interrupt delivery does not "
463 "seem to work\n", dev->name);
464 }
465 prism2_io_debug_error(dev, 3);
466 res = -ETIMEDOUT;
467 goto done;
468 }
469
470 if (resp0 != NULL)
471 *resp0 = entry->resp0;
472#ifndef final_version
473 if (entry->res) {
474 printk(KERN_DEBUG "%s: CMD=0x%04x => res=0x%02x, "
475 "resp0=0x%04x\n",
476 dev->name, cmd, entry->res, entry->resp0);
477 }
478#endif /* final_version */
479
480 res = entry->res;
481 done:
482 hostap_cmd_queue_free(local, entry, 1);
483 return res;
484}
485
486
487/**
488 * hfa384x_cmd_callback - Issue a Prism2 command; callback when completed
489 * @dev: pointer to net_device
490 * @cmd: Prism2 command code (HFA384X_CMD_CODE_*)
491 * @param0: value for Param0 register
492 * @callback: command completion callback function (%NULL = no callback)
493 * @context: context data to be given to the callback function
494 *
495 * Issue given command (possibly after waiting in command queue) and use
496 * callback function to indicate command completion. This can be called both
497 * from user and interrupt context. The callback function will be called in
498 * hardware IRQ context. It can be %NULL, when no function is called when
499 * command is completed.
500 */
501static int hfa384x_cmd_callback(struct net_device *dev, u16 cmd, u16 param0,
502 void (*callback)(struct net_device *dev,
503 long context, u16 resp0,
504 u16 status),
505 long context)
506{
507 struct hostap_interface *iface;
508 local_info_t *local;
509 int issue, ret;
510 unsigned long flags;
511 struct hostap_cmd_queue *entry;
512
513 iface = netdev_priv(dev);
514 local = iface->local;
515
516 if (local->cmd_queue_len >= HOSTAP_CMD_QUEUE_MAX_LEN + 2) {
517 printk(KERN_DEBUG "%s: hfa384x_cmd: cmd_queue full\n",
518 dev->name);
519 return -1;
520 }
521
522 entry = (struct hostap_cmd_queue *)
523 kmalloc(sizeof(*entry), GFP_ATOMIC);
524 if (entry == NULL) {
525 printk(KERN_DEBUG "%s: hfa384x_cmd_callback - kmalloc "
526 "failed\n", dev->name);
527 return -ENOMEM;
528 }
529 memset(entry, 0, sizeof(*entry));
530 atomic_set(&entry->usecnt, 1);
531 entry->type = CMD_CALLBACK;
532 entry->cmd = cmd;
533 entry->param0 = param0;
534 entry->callback = callback;
535 entry->context = context;
536
537 spin_lock_irqsave(&local->cmdlock, flags);
538 issue = list_empty(&local->cmd_queue);
539 if (issue)
540 entry->issuing = 1;
541 list_add_tail(&entry->list, &local->cmd_queue);
542 local->cmd_queue_len++;
543 spin_unlock_irqrestore(&local->cmdlock, flags);
544
545 if (issue && hfa384x_cmd_issue(dev, entry))
546 ret = -ETIMEDOUT;
547 else
548 ret = 0;
549
550 hostap_cmd_queue_free(local, entry, ret);
551
552 return ret;
553}
554
555
556/**
557 * __hfa384x_cmd_no_wait - Issue a Prism2 command (private)
558 * @dev: pointer to net_device
559 * @cmd: Prism2 command code (HFA384X_CMD_CODE_*)
560 * @param0: value for Param0 register
561 * @io_debug_num: I/O debug error number
562 *
563 * Shared helper function for hfa384x_cmd_wait() and hfa384x_cmd_no_wait().
564 */
565static int __hfa384x_cmd_no_wait(struct net_device *dev, u16 cmd, u16 param0,
566 int io_debug_num)
567{
568 int tries;
569 u16 reg;
570
571 /* wait until busy bit is clear; this should always be clear since the
572 * commands are serialized */
573 tries = HFA384X_CMD_BUSY_TIMEOUT;
574 while (HFA384X_INW(HFA384X_CMD_OFF) & HFA384X_CMD_BUSY && tries > 0) {
575 tries--;
576 udelay(1);
577 }
578 if (tries == 0) {
579 reg = HFA384X_INW(HFA384X_CMD_OFF);
580 prism2_io_debug_error(dev, io_debug_num);
581 printk(KERN_DEBUG "%s: __hfa384x_cmd_no_wait(%d) - timeout - "
582 "reg=0x%04x\n", dev->name, io_debug_num, reg);
583 return -ETIMEDOUT;
584 }
585
586 /* write command */
587 HFA384X_OUTW(param0, HFA384X_PARAM0_OFF);
588 HFA384X_OUTW(cmd, HFA384X_CMD_OFF);
589
590 return 0;
591}
592
593
594/**
595 * hfa384x_cmd_wait - Issue a Prism2 command and busy wait for completion
596 * @dev: pointer to net_device
597 * @cmd: Prism2 command code (HFA384X_CMD_CODE_*)
598 * @param0: value for Param0 register
599 */
600static int hfa384x_cmd_wait(struct net_device *dev, u16 cmd, u16 param0)
601{
602 int res, tries;
603 u16 reg;
604
605 res = __hfa384x_cmd_no_wait(dev, cmd, param0, 4);
606 if (res)
607 return res;
608
609 /* wait for command completion */
610 if ((cmd & HFA384X_CMDCODE_MASK) == HFA384X_CMDCODE_DOWNLOAD)
611 tries = HFA384X_DL_COMPL_TIMEOUT;
612 else
613 tries = HFA384X_CMD_COMPL_TIMEOUT;
614
615 while (!(HFA384X_INW(HFA384X_EVSTAT_OFF) & HFA384X_EV_CMD) &&
616 tries > 0) {
617 tries--;
618 udelay(10);
619 }
620 if (tries == 0) {
621 reg = HFA384X_INW(HFA384X_EVSTAT_OFF);
622 prism2_io_debug_error(dev, 5);
623 printk(KERN_DEBUG "%s: hfa384x_cmd_wait - timeout2 - "
624 "reg=0x%04x\n", dev->name, reg);
625 return -ETIMEDOUT;
626 }
627
628 res = (HFA384X_INW(HFA384X_STATUS_OFF) &
629 (BIT(14) | BIT(13) | BIT(12) | BIT(11) | BIT(10) | BIT(9) |
630 BIT(8))) >> 8;
631#ifndef final_version
632 if (res) {
633 printk(KERN_DEBUG "%s: CMD=0x%04x => res=0x%02x\n",
634 dev->name, cmd, res);
635 }
636#endif
637
638 HFA384X_OUTW(HFA384X_EV_CMD, HFA384X_EVACK_OFF);
639
640 return res;
641}
642
643
644/**
645 * hfa384x_cmd_no_wait - Issue a Prism2 command; do not wait for completion
646 * @dev: pointer to net_device
647 * @cmd: Prism2 command code (HFA384X_CMD_CODE_*)
648 * @param0: value for Param0 register
649 */
650static inline int hfa384x_cmd_no_wait(struct net_device *dev, u16 cmd,
651 u16 param0)
652{
653 return __hfa384x_cmd_no_wait(dev, cmd, param0, 6);
654}
655
656
657/**
658 * prism2_cmd_ev - Prism2 command completion event handler
659 * @dev: pointer to net_device
660 *
661 * Interrupt handler for command completion events. Called by the main
662 * interrupt handler in hardware IRQ context. Read Resp0 and status registers
663 * from the hardware and ACK the event. Depending on the issued command type
664 * either wake up the sleeping process that is waiting for command completion
665 * or call the callback function. Issue the next command, if one is pending.
666 */
667static void prism2_cmd_ev(struct net_device *dev)
668{
669 struct hostap_interface *iface;
670 local_info_t *local;
671 struct hostap_cmd_queue *entry = NULL;
672
673 iface = netdev_priv(dev);
674 local = iface->local;
675
676 spin_lock(&local->cmdlock);
677 if (!list_empty(&local->cmd_queue)) {
678 entry = list_entry(local->cmd_queue.next,
679 struct hostap_cmd_queue, list);
680 atomic_inc(&entry->usecnt);
681 list_del_init(&entry->list);
682 local->cmd_queue_len--;
683
684 if (!entry->issued) {
685 printk(KERN_DEBUG "%s: Command completion event, but "
686 "cmd not issued\n", dev->name);
687 __hostap_cmd_queue_free(local, entry, 1);
688 entry = NULL;
689 }
690 }
691 spin_unlock(&local->cmdlock);
692
693 if (!entry) {
694 HFA384X_OUTW(HFA384X_EV_CMD, HFA384X_EVACK_OFF);
695 printk(KERN_DEBUG "%s: Command completion event, but no "
696 "pending commands\n", dev->name);
697 return;
698 }
699
700 entry->resp0 = HFA384X_INW(HFA384X_RESP0_OFF);
701 entry->res = (HFA384X_INW(HFA384X_STATUS_OFF) &
702 (BIT(14) | BIT(13) | BIT(12) | BIT(11) | BIT(10) |
703 BIT(9) | BIT(8))) >> 8;
704 HFA384X_OUTW(HFA384X_EV_CMD, HFA384X_EVACK_OFF);
705
706 /* TODO: rest of the CmdEv handling could be moved to tasklet */
707 if (entry->type == CMD_SLEEP) {
708 entry->type = CMD_COMPLETED;
709 wake_up_interruptible(&entry->compl);
710 } else if (entry->type == CMD_CALLBACK) {
711 if (entry->callback)
712 entry->callback(dev, entry->context, entry->resp0,
713 entry->res);
714 } else {
715 printk(KERN_DEBUG "%s: Invalid command completion type %d\n",
716 dev->name, entry->type);
717 }
718 hostap_cmd_queue_free(local, entry, 1);
719
720 /* issue next command, if pending */
721 entry = NULL;
722 spin_lock(&local->cmdlock);
723 if (!list_empty(&local->cmd_queue)) {
724 entry = list_entry(local->cmd_queue.next,
725 struct hostap_cmd_queue, list);
726 if (entry->issuing) {
727 /* hfa384x_cmd() has already started issuing this
728 * command, so do not start here */
729 entry = NULL;
730 }
731 if (entry)
732 atomic_inc(&entry->usecnt);
733 }
734 spin_unlock(&local->cmdlock);
735
736 if (entry) {
737 /* issue next command; if command issuing fails, remove the
738 * entry from cmd_queue */
739 int res = hfa384x_cmd_issue(dev, entry);
740 spin_lock(&local->cmdlock);
741 __hostap_cmd_queue_free(local, entry, res);
742 spin_unlock(&local->cmdlock);
743 }
744}
745
746
747static inline int hfa384x_wait_offset(struct net_device *dev, u16 o_off)
748{
749 int tries = HFA384X_BAP_BUSY_TIMEOUT;
750 int res = HFA384X_INW(o_off) & HFA384X_OFFSET_BUSY;
751
752 while (res && tries > 0) {
753 tries--;
754 udelay(1);
755 res = HFA384X_INW(o_off) & HFA384X_OFFSET_BUSY;
756 }
757 return res;
758}
759
760
761/* Offset must be even */
762static int hfa384x_setup_bap(struct net_device *dev, u16 bap, u16 id,
763 int offset)
764{
765 u16 o_off, s_off;
766 int ret = 0;
767
768 if (offset % 2 || bap > 1)
769 return -EINVAL;
770
771 if (bap == BAP1) {
772 o_off = HFA384X_OFFSET1_OFF;
773 s_off = HFA384X_SELECT1_OFF;
774 } else {
775 o_off = HFA384X_OFFSET0_OFF;
776 s_off = HFA384X_SELECT0_OFF;
777 }
778
779 if (hfa384x_wait_offset(dev, o_off)) {
780 prism2_io_debug_error(dev, 7);
781 printk(KERN_DEBUG "%s: hfa384x_setup_bap - timeout before\n",
782 dev->name);
783 ret = -ETIMEDOUT;
784 goto out;
785 }
786
787 HFA384X_OUTW(id, s_off);
788 HFA384X_OUTW(offset, o_off);
789
790 if (hfa384x_wait_offset(dev, o_off)) {
791 prism2_io_debug_error(dev, 8);
792 printk(KERN_DEBUG "%s: hfa384x_setup_bap - timeout after\n",
793 dev->name);
794 ret = -ETIMEDOUT;
795 goto out;
796 }
797#ifndef final_version
798 if (HFA384X_INW(o_off) & HFA384X_OFFSET_ERR) {
799 prism2_io_debug_error(dev, 9);
800 printk(KERN_DEBUG "%s: hfa384x_setup_bap - offset error "
801 "(%d,0x04%x,%d); reg=0x%04x\n",
802 dev->name, bap, id, offset, HFA384X_INW(o_off));
803 ret = -EINVAL;
804 }
805#endif
806
807 out:
808 return ret;
809}
810
811
812static int hfa384x_get_rid(struct net_device *dev, u16 rid, void *buf, int len,
813 int exact_len)
814{
815 struct hostap_interface *iface;
816 local_info_t *local;
817 int res, rlen = 0;
818 struct hfa384x_rid_hdr rec;
819
820 iface = netdev_priv(dev);
821 local = iface->local;
822
823 if (local->no_pri) {
824 printk(KERN_DEBUG "%s: cannot get RID %04x (len=%d) - no PRI "
825 "f/w\n", dev->name, rid, len);
826 return -ENOTTY; /* Well.. not really correct, but return
827 * something unique enough.. */
828 }
829
830 if ((local->func->card_present && !local->func->card_present(local)) ||
831 local->hw_downloading)
832 return -ENODEV;
833
834 res = down_interruptible(&local->rid_bap_sem);
835 if (res)
836 return res;
837
838 res = hfa384x_cmd(dev, HFA384X_CMDCODE_ACCESS, rid, NULL, NULL);
839 if (res) {
840 printk(KERN_DEBUG "%s: hfa384x_get_rid: CMDCODE_ACCESS failed "
841 "(res=%d, rid=%04x, len=%d)\n",
842 dev->name, res, rid, len);
843 up(&local->rid_bap_sem);
844 return res;
845 }
846
847 spin_lock_bh(&local->baplock);
848
849 res = hfa384x_setup_bap(dev, BAP0, rid, 0);
850 if (!res)
851 res = hfa384x_from_bap(dev, BAP0, &rec, sizeof(rec));
852
853 if (le16_to_cpu(rec.len) == 0) {
854 /* RID not available */
855 res = -ENODATA;
856 }
857
858 rlen = (le16_to_cpu(rec.len) - 1) * 2;
859 if (!res && exact_len && rlen != len) {
860 printk(KERN_DEBUG "%s: hfa384x_get_rid - RID len mismatch: "
861 "rid=0x%04x, len=%d (expected %d)\n",
862 dev->name, rid, rlen, len);
863 res = -ENODATA;
864 }
865
866 if (!res)
867 res = hfa384x_from_bap(dev, BAP0, buf, len);
868
869 spin_unlock_bh(&local->baplock);
870 up(&local->rid_bap_sem);
871
872 if (res) {
873 if (res != -ENODATA)
874 printk(KERN_DEBUG "%s: hfa384x_get_rid (rid=%04x, "
875 "len=%d) - failed - res=%d\n", dev->name, rid,
876 len, res);
877 if (res == -ETIMEDOUT)
878 prism2_hw_reset(dev);
879 return res;
880 }
881
882 return rlen;
883}
884
885
886static int hfa384x_set_rid(struct net_device *dev, u16 rid, void *buf, int len)
887{
888 struct hostap_interface *iface;
889 local_info_t *local;
890 struct hfa384x_rid_hdr rec;
891 int res;
892
893 iface = netdev_priv(dev);
894 local = iface->local;
895
896 if (local->no_pri) {
897 printk(KERN_DEBUG "%s: cannot set RID %04x (len=%d) - no PRI "
898 "f/w\n", dev->name, rid, len);
899 return -ENOTTY; /* Well.. not really correct, but return
900 * something unique enough.. */
901 }
902
903 if ((local->func->card_present && !local->func->card_present(local)) ||
904 local->hw_downloading)
905 return -ENODEV;
906
907 rec.rid = cpu_to_le16(rid);
908 /* RID len in words and +1 for rec.rid */
909 rec.len = cpu_to_le16(len / 2 + len % 2 + 1);
910
911 res = down_interruptible(&local->rid_bap_sem);
912 if (res)
913 return res;
914
915 spin_lock_bh(&local->baplock);
916 res = hfa384x_setup_bap(dev, BAP0, rid, 0);
917 if (!res)
918 res = hfa384x_to_bap(dev, BAP0, &rec, sizeof(rec));
919 if (!res)
920 res = hfa384x_to_bap(dev, BAP0, buf, len);
921 spin_unlock_bh(&local->baplock);
922
923 if (res) {
924 printk(KERN_DEBUG "%s: hfa384x_set_rid (rid=%04x, len=%d) - "
925 "failed - res=%d\n", dev->name, rid, len, res);
926 up(&local->rid_bap_sem);
927 return res;
928 }
929
930 res = hfa384x_cmd(dev, HFA384X_CMDCODE_ACCESS_WRITE, rid, NULL, NULL);
931 up(&local->rid_bap_sem);
932 if (res) {
933 printk(KERN_DEBUG "%s: hfa384x_set_rid: CMDCODE_ACCESS_WRITE "
934 "failed (res=%d, rid=%04x, len=%d)\n",
935 dev->name, res, rid, len);
936 return res;
937 }
938
939 if (res == -ETIMEDOUT)
940 prism2_hw_reset(dev);
941
942 return res;
943}
944
945
946static void hfa384x_disable_interrupts(struct net_device *dev)
947{
948 /* disable interrupts and clear event status */
949 HFA384X_OUTW(0, HFA384X_INTEN_OFF);
950 HFA384X_OUTW(0xffff, HFA384X_EVACK_OFF);
951}
952
953
954static void hfa384x_enable_interrupts(struct net_device *dev)
955{
956 /* ack pending events and enable interrupts from selected events */
957 HFA384X_OUTW(0xffff, HFA384X_EVACK_OFF);
958 HFA384X_OUTW(HFA384X_EVENT_MASK, HFA384X_INTEN_OFF);
959}
960
961
962static void hfa384x_events_no_bap0(struct net_device *dev)
963{
964 HFA384X_OUTW(HFA384X_EVENT_MASK & ~HFA384X_BAP0_EVENTS,
965 HFA384X_INTEN_OFF);
966}
967
968
969static void hfa384x_events_all(struct net_device *dev)
970{
971 HFA384X_OUTW(HFA384X_EVENT_MASK, HFA384X_INTEN_OFF);
972}
973
974
975static void hfa384x_events_only_cmd(struct net_device *dev)
976{
977 HFA384X_OUTW(HFA384X_EV_CMD, HFA384X_INTEN_OFF);
978}
979
980
981static u16 hfa384x_allocate_fid(struct net_device *dev, int len)
982{
983 u16 fid;
984 unsigned long delay;
985
986 /* FIX: this could be replace with hfa384x_cmd() if the Alloc event
987 * below would be handled like CmdCompl event (sleep here, wake up from
988 * interrupt handler */
989 if (hfa384x_cmd_wait(dev, HFA384X_CMDCODE_ALLOC, len)) {
990 printk(KERN_DEBUG "%s: cannot allocate fid, len=%d\n",
991 dev->name, len);
992 return 0xffff;
993 }
994
995 delay = jiffies + HFA384X_ALLOC_COMPL_TIMEOUT;
996 while (!(HFA384X_INW(HFA384X_EVSTAT_OFF) & HFA384X_EV_ALLOC) &&
997 time_before(jiffies, delay))
998 yield();
999 if (!(HFA384X_INW(HFA384X_EVSTAT_OFF) & HFA384X_EV_ALLOC)) {
1000 printk("%s: fid allocate, len=%d - timeout\n", dev->name, len);
1001 return 0xffff;
1002 }
1003
1004 fid = HFA384X_INW(HFA384X_ALLOCFID_OFF);
1005 HFA384X_OUTW(HFA384X_EV_ALLOC, HFA384X_EVACK_OFF);
1006
1007 return fid;
1008}
1009
1010
1011static int prism2_reset_port(struct net_device *dev)
1012{
1013 struct hostap_interface *iface;
1014 local_info_t *local;
1015 int res;
1016
1017 iface = netdev_priv(dev);
1018 local = iface->local;
1019
1020 if (!local->dev_enabled)
1021 return 0;
1022
1023 res = hfa384x_cmd(dev, HFA384X_CMDCODE_DISABLE, 0,
1024 NULL, NULL);
1025 if (res)
1026 printk(KERN_DEBUG "%s: reset port failed to disable port\n",
1027 dev->name);
1028 else {
1029 res = hfa384x_cmd(dev, HFA384X_CMDCODE_ENABLE, 0,
1030 NULL, NULL);
1031 if (res)
1032 printk(KERN_DEBUG "%s: reset port failed to enable "
1033 "port\n", dev->name);
1034 }
1035
1036 /* It looks like at least some STA firmware versions reset
1037 * fragmentation threshold back to 2346 after enable command. Restore
1038 * the configured value, if it differs from this default. */
1039 if (local->fragm_threshold != 2346 &&
1040 hostap_set_word(dev, HFA384X_RID_FRAGMENTATIONTHRESHOLD,
1041 local->fragm_threshold)) {
1042 printk(KERN_DEBUG "%s: failed to restore fragmentation "
1043 "threshold (%d) after Port0 enable\n",
1044 dev->name, local->fragm_threshold);
1045 }
1046
1047 return res;
1048}
1049
1050
1051static int prism2_get_version_info(struct net_device *dev, u16 rid,
1052 const char *txt)
1053{
1054 struct hfa384x_comp_ident comp;
1055 struct hostap_interface *iface;
1056 local_info_t *local;
1057
1058 iface = netdev_priv(dev);
1059 local = iface->local;
1060
1061 if (local->no_pri) {
1062 /* PRI f/w not yet available - cannot read RIDs */
1063 return -1;
1064 }
1065 if (hfa384x_get_rid(dev, rid, &comp, sizeof(comp), 1) < 0) {
1066 printk(KERN_DEBUG "Could not get RID for component %s\n", txt);
1067 return -1;
1068 }
1069
1070 printk(KERN_INFO "%s: %s: id=0x%02x v%d.%d.%d\n", dev->name, txt,
1071 __le16_to_cpu(comp.id), __le16_to_cpu(comp.major),
1072 __le16_to_cpu(comp.minor), __le16_to_cpu(comp.variant));
1073 return 0;
1074}
1075
1076
1077static int prism2_setup_rids(struct net_device *dev)
1078{
1079 struct hostap_interface *iface;
1080 local_info_t *local;
1081 u16 tmp;
1082 int ret = 0;
1083
1084 iface = netdev_priv(dev);
1085 local = iface->local;
1086
1087 hostap_set_word(dev, HFA384X_RID_TICKTIME, 2000);
1088
1089 if (!local->fw_ap) {
1090 tmp = hostap_get_porttype(local);
1091 ret = hostap_set_word(dev, HFA384X_RID_CNFPORTTYPE, tmp);
1092 if (ret) {
1093 printk("%s: Port type setting to %d failed\n",
1094 dev->name, tmp);
1095 goto fail;
1096 }
1097 }
1098
1099 /* Setting SSID to empty string seems to kill the card in Host AP mode
1100 */
1101 if (local->iw_mode != IW_MODE_MASTER || local->essid[0] != '\0') {
1102 ret = hostap_set_string(dev, HFA384X_RID_CNFOWNSSID,
1103 local->essid);
1104 if (ret) {
1105 printk("%s: AP own SSID setting failed\n", dev->name);
1106 goto fail;
1107 }
1108 }
1109
1110 ret = hostap_set_word(dev, HFA384X_RID_CNFMAXDATALEN,
1111 PRISM2_DATA_MAXLEN);
1112 if (ret) {
1113 printk("%s: MAC data length setting to %d failed\n",
1114 dev->name, PRISM2_DATA_MAXLEN);
1115 goto fail;
1116 }
1117
1118 if (hfa384x_get_rid(dev, HFA384X_RID_CHANNELLIST, &tmp, 2, 1) < 0) {
1119 printk("%s: Channel list read failed\n", dev->name);
1120 ret = -EINVAL;
1121 goto fail;
1122 }
1123 local->channel_mask = __le16_to_cpu(tmp);
1124
1125 if (local->channel < 1 || local->channel > 14 ||
1126 !(local->channel_mask & (1 << (local->channel - 1)))) {
1127 printk(KERN_WARNING "%s: Channel setting out of range "
1128 "(%d)!\n", dev->name, local->channel);
1129 ret = -EBUSY;
1130 goto fail;
1131 }
1132
1133 ret = hostap_set_word(dev, HFA384X_RID_CNFOWNCHANNEL, local->channel);
1134 if (ret) {
1135 printk("%s: Channel setting to %d failed\n",
1136 dev->name, local->channel);
1137 goto fail;
1138 }
1139
1140 ret = hostap_set_word(dev, HFA384X_RID_CNFBEACONINT,
1141 local->beacon_int);
1142 if (ret) {
1143 printk("%s: Beacon interval setting to %d failed\n",
1144 dev->name, local->beacon_int);
1145 /* this may fail with Symbol/Lucent firmware */
1146 if (ret == -ETIMEDOUT)
1147 goto fail;
1148 }
1149
1150 ret = hostap_set_word(dev, HFA384X_RID_CNFOWNDTIMPERIOD,
1151 local->dtim_period);
1152 if (ret) {
1153 printk("%s: DTIM period setting to %d failed\n",
1154 dev->name, local->dtim_period);
1155 /* this may fail with Symbol/Lucent firmware */
1156 if (ret == -ETIMEDOUT)
1157 goto fail;
1158 }
1159
1160 ret = hostap_set_word(dev, HFA384X_RID_PROMISCUOUSMODE,
1161 local->is_promisc);
1162 if (ret)
1163 printk(KERN_INFO "%s: Setting promiscuous mode (%d) failed\n",
1164 dev->name, local->is_promisc);
1165
1166 if (!local->fw_ap) {
1167 ret = hostap_set_string(dev, HFA384X_RID_CNFDESIREDSSID,
1168 local->essid);
1169 if (ret) {
1170 printk("%s: Desired SSID setting failed\n", dev->name);
1171 goto fail;
1172 }
1173 }
1174
1175 /* Setup TXRateControl, defaults to allow use of 1, 2, 5.5, and
1176 * 11 Mbps in automatic TX rate fallback and 1 and 2 Mbps as basic
1177 * rates */
1178 if (local->tx_rate_control == 0) {
1179 local->tx_rate_control =
1180 HFA384X_RATES_1MBPS |
1181 HFA384X_RATES_2MBPS |
1182 HFA384X_RATES_5MBPS |
1183 HFA384X_RATES_11MBPS;
1184 }
1185 if (local->basic_rates == 0)
1186 local->basic_rates = HFA384X_RATES_1MBPS | HFA384X_RATES_2MBPS;
1187
1188 if (!local->fw_ap) {
1189 ret = hostap_set_word(dev, HFA384X_RID_TXRATECONTROL,
1190 local->tx_rate_control);
1191 if (ret) {
1192 printk("%s: TXRateControl setting to %d failed\n",
1193 dev->name, local->tx_rate_control);
1194 goto fail;
1195 }
1196
1197 ret = hostap_set_word(dev, HFA384X_RID_CNFSUPPORTEDRATES,
1198 local->tx_rate_control);
1199 if (ret) {
1200 printk("%s: cnfSupportedRates setting to %d failed\n",
1201 dev->name, local->tx_rate_control);
1202 }
1203
1204 ret = hostap_set_word(dev, HFA384X_RID_CNFBASICRATES,
1205 local->basic_rates);
1206 if (ret) {
1207 printk("%s: cnfBasicRates setting to %d failed\n",
1208 dev->name, local->basic_rates);
1209 }
1210
1211 ret = hostap_set_word(dev, HFA384X_RID_CREATEIBSS, 1);
1212 if (ret) {
1213 printk("%s: Create IBSS setting to 1 failed\n",
1214 dev->name);
1215 }
1216 }
1217
1218 if (local->name_set)
1219 (void) hostap_set_string(dev, HFA384X_RID_CNFOWNNAME,
1220 local->name);
1221
1222 if (hostap_set_encryption(local)) {
1223 printk(KERN_INFO "%s: could not configure encryption\n",
1224 dev->name);
1225 }
1226
1227 (void) hostap_set_antsel(local);
1228
1229 if (hostap_set_roaming(local)) {
1230 printk(KERN_INFO "%s: could not set host roaming\n",
1231 dev->name);
1232 }
1233
1234 if (local->sta_fw_ver >= PRISM2_FW_VER(1,6,3) &&
1235 hostap_set_word(dev, HFA384X_RID_CNFENHSECURITY, local->enh_sec))
1236 printk(KERN_INFO "%s: cnfEnhSecurity setting to 0x%x failed\n",
1237 dev->name, local->enh_sec);
1238
1239 /* 32-bit tallies were added in STA f/w 0.8.0, but they were apparently
1240 * not working correctly (last seven counters report bogus values).
1241 * This has been fixed in 0.8.2, so enable 32-bit tallies only
1242 * beginning with that firmware version. Another bug fix for 32-bit
1243 * tallies in 1.4.0; should 16-bit tallies be used for some other
1244 * versions, too? */
1245 if (local->sta_fw_ver >= PRISM2_FW_VER(0,8,2)) {
1246 if (hostap_set_word(dev, HFA384X_RID_CNFTHIRTY2TALLY, 1)) {
1247 printk(KERN_INFO "%s: cnfThirty2Tally setting "
1248 "failed\n", dev->name);
1249 local->tallies32 = 0;
1250 } else
1251 local->tallies32 = 1;
1252 } else
1253 local->tallies32 = 0;
1254
1255 hostap_set_auth_algs(local);
1256
1257 if (hostap_set_word(dev, HFA384X_RID_FRAGMENTATIONTHRESHOLD,
1258 local->fragm_threshold)) {
1259 printk(KERN_INFO "%s: setting FragmentationThreshold to %d "
1260 "failed\n", dev->name, local->fragm_threshold);
1261 }
1262
1263 if (hostap_set_word(dev, HFA384X_RID_RTSTHRESHOLD,
1264 local->rts_threshold)) {
1265 printk(KERN_INFO "%s: setting RTSThreshold to %d failed\n",
1266 dev->name, local->rts_threshold);
1267 }
1268
1269 if (local->manual_retry_count >= 0 &&
1270 hostap_set_word(dev, HFA384X_RID_CNFALTRETRYCOUNT,
1271 local->manual_retry_count)) {
1272 printk(KERN_INFO "%s: setting cnfAltRetryCount to %d failed\n",
1273 dev->name, local->manual_retry_count);
1274 }
1275
1276 if (local->sta_fw_ver >= PRISM2_FW_VER(1,3,1) &&
1277 hfa384x_get_rid(dev, HFA384X_RID_CNFDBMADJUST, &tmp, 2, 1) == 2) {
1278 local->rssi_to_dBm = le16_to_cpu(tmp);
1279 }
1280
1281 if (local->sta_fw_ver >= PRISM2_FW_VER(1,7,0) && local->wpa &&
1282 hostap_set_word(dev, HFA384X_RID_SSNHANDLINGMODE, 1)) {
1283 printk(KERN_INFO "%s: setting ssnHandlingMode to 1 failed\n",
1284 dev->name);
1285 }
1286
1287 if (local->sta_fw_ver >= PRISM2_FW_VER(1,7,0) && local->generic_elem &&
1288 hfa384x_set_rid(dev, HFA384X_RID_GENERICELEMENT,
1289 local->generic_elem, local->generic_elem_len)) {
1290 printk(KERN_INFO "%s: setting genericElement failed\n",
1291 dev->name);
1292 }
1293
1294 fail:
1295 return ret;
1296}
1297
1298
1299static int prism2_hw_init(struct net_device *dev, int initial)
1300{
1301 struct hostap_interface *iface;
1302 local_info_t *local;
1303 int ret, first = 1;
1304 unsigned long start, delay;
1305
1306 PDEBUG(DEBUG_FLOW, "prism2_hw_init()\n");
1307
1308 iface = netdev_priv(dev);
1309 local = iface->local;
1310
1311 clear_bit(HOSTAP_BITS_TRANSMIT, &local->bits);
1312
1313 init:
1314 /* initialize HFA 384x */
1315 ret = hfa384x_cmd_no_wait(dev, HFA384X_CMDCODE_INIT, 0);
1316 if (ret) {
1317 printk(KERN_INFO "%s: first command failed - assuming card "
1318 "does not have primary firmware\n", dev_info);
1319 }
1320
1321 if (first && (HFA384X_INW(HFA384X_EVSTAT_OFF) & HFA384X_EV_CMD)) {
1322 /* EvStat has Cmd bit set in some cases, so retry once if no
1323 * wait was needed */
1324 HFA384X_OUTW(HFA384X_EV_CMD, HFA384X_EVACK_OFF);
1325 printk(KERN_DEBUG "%s: init command completed too quickly - "
1326 "retrying\n", dev->name);
1327 first = 0;
1328 goto init;
1329 }
1330
1331 start = jiffies;
1332 delay = jiffies + HFA384X_INIT_TIMEOUT;
1333 while (!(HFA384X_INW(HFA384X_EVSTAT_OFF) & HFA384X_EV_CMD) &&
1334 time_before(jiffies, delay))
1335 yield();
1336 if (!(HFA384X_INW(HFA384X_EVSTAT_OFF) & HFA384X_EV_CMD)) {
1337 printk(KERN_DEBUG "%s: assuming no Primary image in "
1338 "flash - card initialization not completed\n",
1339 dev_info);
1340 local->no_pri = 1;
1341#ifdef PRISM2_DOWNLOAD_SUPPORT
1342 if (local->sram_type == -1)
1343 local->sram_type = prism2_get_ram_size(local);
1344#endif /* PRISM2_DOWNLOAD_SUPPORT */
1345 return 1;
1346 }
1347 local->no_pri = 0;
1348 printk(KERN_DEBUG "prism2_hw_init: initialized in %lu ms\n",
1349 (jiffies - start) * 1000 / HZ);
1350 HFA384X_OUTW(HFA384X_EV_CMD, HFA384X_EVACK_OFF);
1351 return 0;
1352}
1353
1354
1355static int prism2_hw_init2(struct net_device *dev, int initial)
1356{
1357 struct hostap_interface *iface;
1358 local_info_t *local;
1359 int i;
1360
1361 iface = netdev_priv(dev);
1362 local = iface->local;
1363
1364#ifdef PRISM2_DOWNLOAD_SUPPORT
1365 kfree(local->pda);
1366 if (local->no_pri)
1367 local->pda = NULL;
1368 else
1369 local->pda = prism2_read_pda(dev);
1370#endif /* PRISM2_DOWNLOAD_SUPPORT */
1371
1372 hfa384x_disable_interrupts(dev);
1373
1374#ifndef final_version
1375 HFA384X_OUTW(HFA384X_MAGIC, HFA384X_SWSUPPORT0_OFF);
1376 if (HFA384X_INW(HFA384X_SWSUPPORT0_OFF) != HFA384X_MAGIC) {
1377 printk("SWSUPPORT0 write/read failed: %04X != %04X\n",
1378 HFA384X_INW(HFA384X_SWSUPPORT0_OFF), HFA384X_MAGIC);
1379 goto failed;
1380 }
1381#endif
1382
1383 if (initial || local->pri_only) {
1384 hfa384x_events_only_cmd(dev);
1385 /* get card version information */
1386 if (prism2_get_version_info(dev, HFA384X_RID_NICID, "NIC") ||
1387 prism2_get_version_info(dev, HFA384X_RID_PRIID, "PRI")) {
1388 hfa384x_disable_interrupts(dev);
1389 goto failed;
1390 }
1391
1392 if (prism2_get_version_info(dev, HFA384X_RID_STAID, "STA")) {
1393 printk(KERN_DEBUG "%s: Failed to read STA f/w version "
1394 "- only Primary f/w present\n", dev->name);
1395 local->pri_only = 1;
1396 return 0;
1397 }
1398 local->pri_only = 0;
1399 hfa384x_disable_interrupts(dev);
1400 }
1401
1402 /* FIX: could convert allocate_fid to use sleeping CmdCompl wait and
1403 * enable interrupts before this. This would also require some sort of
1404 * sleeping AllocEv waiting */
1405
1406 /* allocate TX FIDs */
1407 local->txfid_len = PRISM2_TXFID_LEN;
1408 for (i = 0; i < PRISM2_TXFID_COUNT; i++) {
1409 local->txfid[i] = hfa384x_allocate_fid(dev, local->txfid_len);
1410 if (local->txfid[i] == 0xffff && local->txfid_len > 1600) {
1411 local->txfid[i] = hfa384x_allocate_fid(dev, 1600);
1412 if (local->txfid[i] != 0xffff) {
1413 printk(KERN_DEBUG "%s: Using shorter TX FID "
1414 "(1600 bytes)\n", dev->name);
1415 local->txfid_len = 1600;
1416 }
1417 }
1418 if (local->txfid[i] == 0xffff)
1419 goto failed;
1420 local->intransmitfid[i] = PRISM2_TXFID_EMPTY;
1421 }
1422
1423 hfa384x_events_only_cmd(dev);
1424
1425 if (initial) {
1426 struct list_head *ptr;
1427 prism2_check_sta_fw_version(local);
1428
1429 if (hfa384x_get_rid(dev, HFA384X_RID_CNFOWNMACADDR,
1430 &dev->dev_addr, 6, 1) < 0) {
1431 printk("%s: could not get own MAC address\n",
1432 dev->name);
1433 }
1434 list_for_each(ptr, &local->hostap_interfaces) {
1435 iface = list_entry(ptr, struct hostap_interface, list);
1436 memcpy(iface->dev->dev_addr, dev->dev_addr, ETH_ALEN);
1437 }
1438 } else if (local->fw_ap)
1439 prism2_check_sta_fw_version(local);
1440
1441 prism2_setup_rids(dev);
1442
1443 /* MAC is now configured, but port 0 is not yet enabled */
1444 return 0;
1445
1446 failed:
1447 if (!local->no_pri)
1448 printk(KERN_WARNING "%s: Initialization failed\n", dev_info);
1449 return 1;
1450}
1451
1452
1453static int prism2_hw_enable(struct net_device *dev, int initial)
1454{
1455 struct hostap_interface *iface;
1456 local_info_t *local;
1457 int was_resetting;
1458
1459 iface = netdev_priv(dev);
1460 local = iface->local;
1461 was_resetting = local->hw_resetting;
1462
1463 if (hfa384x_cmd(dev, HFA384X_CMDCODE_ENABLE, 0, NULL, NULL)) {
1464 printk("%s: MAC port 0 enabling failed\n", dev->name);
1465 return 1;
1466 }
1467
1468 local->hw_ready = 1;
1469 local->hw_reset_tries = 0;
1470 local->hw_resetting = 0;
1471 hfa384x_enable_interrupts(dev);
1472
1473 /* at least D-Link DWL-650 seems to require additional port reset
1474 * before it starts acting as an AP, so reset port automatically
1475 * here just in case */
1476 if (initial && prism2_reset_port(dev)) {
1477 printk("%s: MAC port 0 reseting failed\n", dev->name);
1478 return 1;
1479 }
1480
1481 if (was_resetting && netif_queue_stopped(dev)) {
1482 /* If hw_reset() was called during pending transmit, netif
1483 * queue was stopped. Wake it up now since the wlan card has
1484 * been resetted. */
1485 netif_wake_queue(dev);
1486 }
1487
1488 return 0;
1489}
1490
1491
1492static int prism2_hw_config(struct net_device *dev, int initial)
1493{
1494 struct hostap_interface *iface;
1495 local_info_t *local;
1496
1497 iface = netdev_priv(dev);
1498 local = iface->local;
1499
1500 if (local->hw_downloading)
1501 return 1;
1502
1503 if (prism2_hw_init(dev, initial)) {
1504 return local->no_pri ? 0 : 1;
1505 }
1506
1507 if (prism2_hw_init2(dev, initial))
1508 return 1;
1509
1510 /* Enable firmware if secondary image is loaded and at least one of the
1511 * netdevices is up. */
1512 if (!local->pri_only &&
1513 (initial == 0 || (initial == 2 && local->num_dev_open > 0))) {
1514 if (!local->dev_enabled)
1515 prism2_callback(local, PRISM2_CALLBACK_ENABLE);
1516 local->dev_enabled = 1;
1517 return prism2_hw_enable(dev, initial);
1518 }
1519
1520 return 0;
1521}
1522
1523
1524static void prism2_hw_shutdown(struct net_device *dev, int no_disable)
1525{
1526 struct hostap_interface *iface;
1527 local_info_t *local;
1528
1529 iface = netdev_priv(dev);
1530 local = iface->local;
1531
1532 /* Allow only command completion events during disable */
1533 hfa384x_events_only_cmd(dev);
1534
1535 local->hw_ready = 0;
1536 if (local->dev_enabled)
1537 prism2_callback(local, PRISM2_CALLBACK_DISABLE);
1538 local->dev_enabled = 0;
1539
1540 if (local->func->card_present && !local->func->card_present(local)) {
1541 printk(KERN_DEBUG "%s: card already removed or not configured "
1542 "during shutdown\n", dev->name);
1543 return;
1544 }
1545
1546 if ((no_disable & HOSTAP_HW_NO_DISABLE) == 0 &&
1547 hfa384x_cmd(dev, HFA384X_CMDCODE_DISABLE, 0, NULL, NULL))
1548 printk(KERN_WARNING "%s: Shutdown failed\n", dev_info);
1549
1550 hfa384x_disable_interrupts(dev);
1551
1552 if (no_disable & HOSTAP_HW_ENABLE_CMDCOMPL)
1553 hfa384x_events_only_cmd(dev);
1554 else
1555 prism2_clear_cmd_queue(local);
1556}
1557
1558
1559static void prism2_hw_reset(struct net_device *dev)
1560{
1561 struct hostap_interface *iface;
1562 local_info_t *local;
1563
1564#if 0
1565 static long last_reset = 0;
1566
1567 /* do not reset card more than once per second to avoid ending up in a
1568 * busy loop reseting the card */
1569 if (time_before_eq(jiffies, last_reset + HZ))
1570 return;
1571 last_reset = jiffies;
1572#endif
1573
1574 iface = netdev_priv(dev);
1575 local = iface->local;
1576
1577 if (in_interrupt()) {
1578 printk(KERN_DEBUG "%s: driver bug - prism2_hw_reset() called "
1579 "in interrupt context\n", dev->name);
1580 return;
1581 }
1582
1583 if (local->hw_downloading)
1584 return;
1585
1586 if (local->hw_resetting) {
1587 printk(KERN_WARNING "%s: %s: already resetting card - "
1588 "ignoring reset request\n", dev_info, dev->name);
1589 return;
1590 }
1591
1592 local->hw_reset_tries++;
1593 if (local->hw_reset_tries > 10) {
1594 printk(KERN_WARNING "%s: too many reset tries, skipping\n",
1595 dev->name);
1596 return;
1597 }
1598
1599 printk(KERN_WARNING "%s: %s: resetting card\n", dev_info, dev->name);
1600 hfa384x_disable_interrupts(dev);
1601 local->hw_resetting = 1;
1602 if (local->func->cor_sreset) {
1603 /* Host system seems to hang in some cases with high traffic
1604 * load or shared interrupts during COR sreset. Disable shared
1605 * interrupts during reset to avoid these crashes. COS sreset
1606 * takes quite a long time, so it is unfortunate that this
1607 * seems to be needed. Anyway, I do not know of any better way
1608 * of avoiding the crash. */
1609 disable_irq(dev->irq);
1610 local->func->cor_sreset(local);
1611 enable_irq(dev->irq);
1612 }
1613 prism2_hw_shutdown(dev, 1);
1614 prism2_hw_config(dev, 0);
1615 local->hw_resetting = 0;
1616
1617#ifdef PRISM2_DOWNLOAD_SUPPORT
1618 if (local->dl_pri) {
1619 printk(KERN_DEBUG "%s: persistent download of primary "
1620 "firmware\n", dev->name);
1621 if (prism2_download_genesis(local, local->dl_pri) < 0)
1622 printk(KERN_WARNING "%s: download (PRI) failed\n",
1623 dev->name);
1624 }
1625
1626 if (local->dl_sec) {
1627 printk(KERN_DEBUG "%s: persistent download of secondary "
1628 "firmware\n", dev->name);
1629 if (prism2_download_volatile(local, local->dl_sec) < 0)
1630 printk(KERN_WARNING "%s: download (SEC) failed\n",
1631 dev->name);
1632 }
1633#endif /* PRISM2_DOWNLOAD_SUPPORT */
1634
1635 /* TODO: restore beacon TIM bits for STAs that have buffered frames */
1636}
1637
1638
1639static void prism2_schedule_reset(local_info_t *local)
1640{
1641 schedule_work(&local->reset_queue);
1642}
1643
1644
1645/* Called only as scheduled task after noticing card timeout in interrupt
1646 * context */
1647static void handle_reset_queue(void *data)
1648{
1649 local_info_t *local = (local_info_t *) data;
1650
1651 printk(KERN_DEBUG "%s: scheduled card reset\n", local->dev->name);
1652 prism2_hw_reset(local->dev);
1653
1654 if (netif_queue_stopped(local->dev)) {
1655 int i;
1656
1657 for (i = 0; i < PRISM2_TXFID_COUNT; i++)
1658 if (local->intransmitfid[i] == PRISM2_TXFID_EMPTY) {
1659 PDEBUG(DEBUG_EXTRA, "prism2_tx_timeout: "
1660 "wake up queue\n");
1661 netif_wake_queue(local->dev);
1662 break;
1663 }
1664 }
1665}
1666
1667
1668static int prism2_get_txfid_idx(local_info_t *local)
1669{
1670 int idx, end;
1671 unsigned long flags;
1672
1673 spin_lock_irqsave(&local->txfidlock, flags);
1674 end = idx = local->next_txfid;
1675 do {
1676 if (local->intransmitfid[idx] == PRISM2_TXFID_EMPTY) {
1677 local->intransmitfid[idx] = PRISM2_TXFID_RESERVED;
1678 spin_unlock_irqrestore(&local->txfidlock, flags);
1679 return idx;
1680 }
1681 idx++;
1682 if (idx >= PRISM2_TXFID_COUNT)
1683 idx = 0;
1684 } while (idx != end);
1685 spin_unlock_irqrestore(&local->txfidlock, flags);
1686
1687 PDEBUG(DEBUG_EXTRA2, "prism2_get_txfid_idx: no room in txfid buf: "
1688 "packet dropped\n");
1689 local->stats.tx_dropped++;
1690
1691 return -1;
1692}
1693
1694
1695/* Called only from hardware IRQ */
1696static void prism2_transmit_cb(struct net_device *dev, long context,
1697 u16 resp0, u16 res)
1698{
1699 struct hostap_interface *iface;
1700 local_info_t *local;
1701 int idx = (int) context;
1702
1703 iface = netdev_priv(dev);
1704 local = iface->local;
1705
1706 if (res) {
1707 printk(KERN_DEBUG "%s: prism2_transmit_cb - res=0x%02x\n",
1708 dev->name, res);
1709 return;
1710 }
1711
1712 if (idx < 0 || idx >= PRISM2_TXFID_COUNT) {
1713 printk(KERN_DEBUG "%s: prism2_transmit_cb called with invalid "
1714 "idx=%d\n", dev->name, idx);
1715 return;
1716 }
1717
1718 if (!test_and_clear_bit(HOSTAP_BITS_TRANSMIT, &local->bits)) {
1719 printk(KERN_DEBUG "%s: driver bug: prism2_transmit_cb called "
1720 "with no pending transmit\n", dev->name);
1721 }
1722
1723 if (netif_queue_stopped(dev)) {
1724 /* ready for next TX, so wake up queue that was stopped in
1725 * prism2_transmit() */
1726 netif_wake_queue(dev);
1727 }
1728
1729 spin_lock(&local->txfidlock);
1730
1731 /* With reclaim, Resp0 contains new txfid for transmit; the old txfid
1732 * will be automatically allocated for the next TX frame */
1733 local->intransmitfid[idx] = resp0;
1734
1735 PDEBUG(DEBUG_FID, "%s: prism2_transmit_cb: txfid[%d]=0x%04x, "
1736 "resp0=0x%04x, transmit_txfid=0x%04x\n",
1737 dev->name, idx, local->txfid[idx],
1738 resp0, local->intransmitfid[local->next_txfid]);
1739
1740 idx++;
1741 if (idx >= PRISM2_TXFID_COUNT)
1742 idx = 0;
1743 local->next_txfid = idx;
1744
1745 /* check if all TX buffers are occupied */
1746 do {
1747 if (local->intransmitfid[idx] == PRISM2_TXFID_EMPTY) {
1748 spin_unlock(&local->txfidlock);
1749 return;
1750 }
1751 idx++;
1752 if (idx >= PRISM2_TXFID_COUNT)
1753 idx = 0;
1754 } while (idx != local->next_txfid);
1755 spin_unlock(&local->txfidlock);
1756
1757 /* no empty TX buffers, stop queue */
1758 netif_stop_queue(dev);
1759}
1760
1761
1762/* Called only from software IRQ if PCI bus master is not used (with bus master
1763 * this can be called both from software and hardware IRQ) */
1764static int prism2_transmit(struct net_device *dev, int idx)
1765{
1766 struct hostap_interface *iface;
1767 local_info_t *local;
1768 int res;
1769
1770 iface = netdev_priv(dev);
1771 local = iface->local;
1772
1773 /* The driver tries to stop netif queue so that there would not be
1774 * more than one attempt to transmit frames going on; check that this
1775 * is really the case */
1776
1777 if (test_and_set_bit(HOSTAP_BITS_TRANSMIT, &local->bits)) {
1778 printk(KERN_DEBUG "%s: driver bug - prism2_transmit() called "
1779 "when previous TX was pending\n", dev->name);
1780 return -1;
1781 }
1782
1783 /* stop the queue for the time that transmit is pending */
1784 netif_stop_queue(dev);
1785
1786 /* transmit packet */
1787 res = hfa384x_cmd_callback(
1788 dev,
1789 HFA384X_CMDCODE_TRANSMIT | HFA384X_CMD_TX_RECLAIM,
1790 local->txfid[idx],
1791 prism2_transmit_cb, (long) idx);
1792
1793 if (res) {
1794 struct net_device_stats *stats;
1795 printk(KERN_DEBUG "%s: prism2_transmit: CMDCODE_TRANSMIT "
1796 "failed (res=%d)\n", dev->name, res);
1797 stats = hostap_get_stats(dev);
1798 stats->tx_dropped++;
1799 netif_wake_queue(dev);
1800 return -1;
1801 }
1802 dev->trans_start = jiffies;
1803
1804 /* Since we did not wait for command completion, the card continues
1805 * to process on the background and we will finish handling when
1806 * command completion event is handled (prism2_cmd_ev() function) */
1807
1808 return 0;
1809}
1810
1811
1812/* Send IEEE 802.11 frame (convert the header into Prism2 TX descriptor and
1813 * send the payload with this descriptor) */
1814/* Called only from software IRQ */
1815static int prism2_tx_80211(struct sk_buff *skb, struct net_device *dev)
1816{
1817 struct hostap_interface *iface;
1818 local_info_t *local;
1819 struct hfa384x_tx_frame txdesc;
1820 struct hostap_skb_tx_data *meta;
1821 int hdr_len, data_len, idx, res, ret = -1;
1822 u16 tx_control, fc;
1823
1824 iface = netdev_priv(dev);
1825 local = iface->local;
1826
1827 meta = (struct hostap_skb_tx_data *) skb->cb;
1828
1829 prism2_callback(local, PRISM2_CALLBACK_TX_START);
1830
1831 if ((local->func->card_present && !local->func->card_present(local)) ||
1832 !local->hw_ready || local->hw_downloading || local->pri_only) {
1833 if (net_ratelimit()) {
1834 printk(KERN_DEBUG "%s: prism2_tx_80211: hw not ready -"
1835 " skipping\n", dev->name);
1836 }
1837 goto fail;
1838 }
1839
1840 memset(&txdesc, 0, sizeof(txdesc));
1841
1842 /* skb->data starts with txdesc->frame_control */
1843 hdr_len = 24;
1844 memcpy(&txdesc.frame_control, skb->data, hdr_len);
1845 fc = le16_to_cpu(txdesc.frame_control);
1846 if (WLAN_FC_GET_TYPE(fc) == IEEE80211_FTYPE_DATA &&
1847 (fc & IEEE80211_FCTL_FROMDS) && (fc & IEEE80211_FCTL_TODS) &&
1848 skb->len >= 30) {
1849 /* Addr4 */
1850 memcpy(txdesc.addr4, skb->data + hdr_len, ETH_ALEN);
1851 hdr_len += ETH_ALEN;
1852 }
1853
1854 tx_control = local->tx_control;
1855 if (meta->tx_cb_idx) {
1856 tx_control |= HFA384X_TX_CTRL_TX_OK;
1857 txdesc.sw_support = cpu_to_le16(meta->tx_cb_idx);
1858 }
1859 txdesc.tx_control = cpu_to_le16(tx_control);
1860 txdesc.tx_rate = meta->rate;
1861
1862 data_len = skb->len - hdr_len;
1863 txdesc.data_len = cpu_to_le16(data_len);
1864 txdesc.len = cpu_to_be16(data_len);
1865
1866 idx = prism2_get_txfid_idx(local);
1867 if (idx < 0)
1868 goto fail;
1869
1870 if (local->frame_dump & PRISM2_DUMP_TX_HDR)
1871 hostap_dump_tx_header(dev->name, &txdesc);
1872
1873 spin_lock(&local->baplock);
1874 res = hfa384x_setup_bap(dev, BAP0, local->txfid[idx], 0);
1875
1876 if (!res)
1877 res = hfa384x_to_bap(dev, BAP0, &txdesc, sizeof(txdesc));
1878 if (!res)
1879 res = hfa384x_to_bap(dev, BAP0, skb->data + hdr_len,
1880 skb->len - hdr_len);
1881 spin_unlock(&local->baplock);
1882
1883 if (!res)
1884 res = prism2_transmit(dev, idx);
1885 if (res) {
1886 printk(KERN_DEBUG "%s: prism2_tx_80211 - to BAP0 failed\n",
1887 dev->name);
1888 local->intransmitfid[idx] = PRISM2_TXFID_EMPTY;
1889 schedule_work(&local->reset_queue);
1890 goto fail;
1891 }
1892
1893 ret = 0;
1894
1895fail:
1896 prism2_callback(local, PRISM2_CALLBACK_TX_END);
1897 return ret;
1898}
1899
1900
1901/* Some SMP systems have reported number of odd errors with hostap_pci. fid
1902 * register has changed values between consecutive reads for an unknown reason.
1903 * This should really not happen, so more debugging is needed. This test
1904 * version is a big slower, but it will detect most of such register changes
1905 * and will try to get the correct fid eventually. */
1906#define EXTRA_FID_READ_TESTS
1907
1908static inline u16 prism2_read_fid_reg(struct net_device *dev, u16 reg)
1909{
1910#ifdef EXTRA_FID_READ_TESTS
1911 u16 val, val2, val3;
1912 int i;
1913
1914 for (i = 0; i < 10; i++) {
1915 val = HFA384X_INW(reg);
1916 val2 = HFA384X_INW(reg);
1917 val3 = HFA384X_INW(reg);
1918
1919 if (val == val2 && val == val3)
1920 return val;
1921
1922 printk(KERN_DEBUG "%s: detected fid change (try=%d, reg=%04x):"
1923 " %04x %04x %04x\n",
1924 dev->name, i, reg, val, val2, val3);
1925 if ((val == val2 || val == val3) && val != 0)
1926 return val;
1927 if (val2 == val3 && val2 != 0)
1928 return val2;
1929 }
1930 printk(KERN_WARNING "%s: Uhhuh.. could not read good fid from reg "
1931 "%04x (%04x %04x %04x)\n", dev->name, reg, val, val2, val3);
1932 return val;
1933#else /* EXTRA_FID_READ_TESTS */
1934 return HFA384X_INW(reg);
1935#endif /* EXTRA_FID_READ_TESTS */
1936}
1937
1938
1939/* Called only as a tasklet (software IRQ) */
1940static void prism2_rx(local_info_t *local)
1941{
1942 struct net_device *dev = local->dev;
1943 int res, rx_pending = 0;
1944 u16 len, hdr_len, rxfid, status, macport;
1945 struct net_device_stats *stats;
1946 struct hfa384x_rx_frame rxdesc;
1947 struct sk_buff *skb = NULL;
1948
1949 prism2_callback(local, PRISM2_CALLBACK_RX_START);
1950 stats = hostap_get_stats(dev);
1951
1952 rxfid = prism2_read_fid_reg(dev, HFA384X_RXFID_OFF);
1953#ifndef final_version
1954 if (rxfid == 0) {
1955 rxfid = HFA384X_INW(HFA384X_RXFID_OFF);
1956 printk(KERN_DEBUG "prism2_rx: rxfid=0 (next 0x%04x)\n",
1957 rxfid);
1958 if (rxfid == 0) {
1959 schedule_work(&local->reset_queue);
1960 goto rx_dropped;
1961 }
1962 /* try to continue with the new rxfid value */
1963 }
1964#endif
1965
1966 spin_lock(&local->baplock);
1967 res = hfa384x_setup_bap(dev, BAP0, rxfid, 0);
1968 if (!res)
1969 res = hfa384x_from_bap(dev, BAP0, &rxdesc, sizeof(rxdesc));
1970
1971 if (res) {
1972 spin_unlock(&local->baplock);
1973 printk(KERN_DEBUG "%s: copy from BAP0 failed %d\n", dev->name,
1974 res);
1975 if (res == -ETIMEDOUT) {
1976 schedule_work(&local->reset_queue);
1977 }
1978 goto rx_dropped;
1979 }
1980
1981 len = le16_to_cpu(rxdesc.data_len);
1982 hdr_len = sizeof(rxdesc);
1983 status = le16_to_cpu(rxdesc.status);
1984 macport = (status >> 8) & 0x07;
1985
1986 /* Drop frames with too large reported payload length. Monitor mode
1987 * seems to sometimes pass frames (e.g., ctrl::ack) with signed and
1988 * negative value, so allow also values 65522 .. 65534 (-14 .. -2) for
1989 * macport 7 */
1990 if (len > PRISM2_DATA_MAXLEN + 8 /* WEP */) {
1991 if (macport == 7 && local->iw_mode == IW_MODE_MONITOR) {
1992 if (len >= (u16) -14) {
1993 hdr_len -= 65535 - len;
1994 hdr_len--;
1995 }
1996 len = 0;
1997 } else {
1998 spin_unlock(&local->baplock);
1999 printk(KERN_DEBUG "%s: Received frame with invalid "
2000 "length 0x%04x\n", dev->name, len);
2001 hostap_dump_rx_header(dev->name, &rxdesc);
2002 goto rx_dropped;
2003 }
2004 }
2005
2006 skb = dev_alloc_skb(len + hdr_len);
2007 if (!skb) {
2008 spin_unlock(&local->baplock);
2009 printk(KERN_DEBUG "%s: RX failed to allocate skb\n",
2010 dev->name);
2011 goto rx_dropped;
2012 }
2013 skb->dev = dev;
2014 memcpy(skb_put(skb, hdr_len), &rxdesc, hdr_len);
2015
2016 if (len > 0)
2017 res = hfa384x_from_bap(dev, BAP0, skb_put(skb, len), len);
2018 spin_unlock(&local->baplock);
2019 if (res) {
2020 printk(KERN_DEBUG "%s: RX failed to read "
2021 "frame data\n", dev->name);
2022 goto rx_dropped;
2023 }
2024
2025 skb_queue_tail(&local->rx_list, skb);
2026 tasklet_schedule(&local->rx_tasklet);
2027
2028 rx_exit:
2029 prism2_callback(local, PRISM2_CALLBACK_RX_END);
2030 if (!rx_pending) {
2031 HFA384X_OUTW(HFA384X_EV_RX, HFA384X_EVACK_OFF);
2032 }
2033
2034 return;
2035
2036 rx_dropped:
2037 stats->rx_dropped++;
2038 if (skb)
2039 dev_kfree_skb(skb);
2040 goto rx_exit;
2041}
2042
2043
2044/* Called only as a tasklet (software IRQ) */
2045static void hostap_rx_skb(local_info_t *local, struct sk_buff *skb)
2046{
2047 struct hfa384x_rx_frame *rxdesc;
2048 struct net_device *dev = skb->dev;
2049 struct hostap_80211_rx_status stats;
2050 int hdrlen, rx_hdrlen;
2051
2052 rx_hdrlen = sizeof(*rxdesc);
2053 if (skb->len < sizeof(*rxdesc)) {
2054 /* Allow monitor mode to receive shorter frames */
2055 if (local->iw_mode == IW_MODE_MONITOR &&
2056 skb->len >= sizeof(*rxdesc) - 30) {
2057 rx_hdrlen = skb->len;
2058 } else {
2059 dev_kfree_skb(skb);
2060 return;
2061 }
2062 }
2063
2064 rxdesc = (struct hfa384x_rx_frame *) skb->data;
2065
2066 if (local->frame_dump & PRISM2_DUMP_RX_HDR &&
2067 skb->len >= sizeof(*rxdesc))
2068 hostap_dump_rx_header(dev->name, rxdesc);
2069
2070 if (le16_to_cpu(rxdesc->status) & HFA384X_RX_STATUS_FCSERR &&
2071 (!local->monitor_allow_fcserr ||
2072 local->iw_mode != IW_MODE_MONITOR))
2073 goto drop;
2074
2075 if (skb->len > PRISM2_DATA_MAXLEN) {
2076 printk(KERN_DEBUG "%s: RX: len(%d) > MAX(%d)\n",
2077 dev->name, skb->len, PRISM2_DATA_MAXLEN);
2078 goto drop;
2079 }
2080
2081 stats.mac_time = le32_to_cpu(rxdesc->time);
2082 stats.signal = rxdesc->signal - local->rssi_to_dBm;
2083 stats.noise = rxdesc->silence - local->rssi_to_dBm;
2084 stats.rate = rxdesc->rate;
2085
2086 /* Convert Prism2 RX structure into IEEE 802.11 header */
2087 hdrlen = hostap_80211_get_hdrlen(le16_to_cpu(rxdesc->frame_control));
2088 if (hdrlen > rx_hdrlen)
2089 hdrlen = rx_hdrlen;
2090
2091 memmove(skb_pull(skb, rx_hdrlen - hdrlen),
2092 &rxdesc->frame_control, hdrlen);
2093
2094 hostap_80211_rx(dev, skb, &stats);
2095 return;
2096
2097 drop:
2098 dev_kfree_skb(skb);
2099}
2100
2101
2102/* Called only as a tasklet (software IRQ) */
2103static void hostap_rx_tasklet(unsigned long data)
2104{
2105 local_info_t *local = (local_info_t *) data;
2106 struct sk_buff *skb;
2107
2108 while ((skb = skb_dequeue(&local->rx_list)) != NULL)
2109 hostap_rx_skb(local, skb);
2110}
2111
2112
2113/* Called only from hardware IRQ */
2114static void prism2_alloc_ev(struct net_device *dev)
2115{
2116 struct hostap_interface *iface;
2117 local_info_t *local;
2118 int idx;
2119 u16 fid;
2120
2121 iface = netdev_priv(dev);
2122 local = iface->local;
2123
2124 fid = prism2_read_fid_reg(dev, HFA384X_ALLOCFID_OFF);
2125
2126 PDEBUG(DEBUG_FID, "FID: interrupt: ALLOC - fid=0x%04x\n", fid);
2127
2128 spin_lock(&local->txfidlock);
2129 idx = local->next_alloc;
2130
2131 do {
2132 if (local->txfid[idx] == fid) {
2133 PDEBUG(DEBUG_FID, "FID: found matching txfid[%d]\n",
2134 idx);
2135
2136#ifndef final_version
2137 if (local->intransmitfid[idx] == PRISM2_TXFID_EMPTY)
2138 printk("Already released txfid found at idx "
2139 "%d\n", idx);
2140 if (local->intransmitfid[idx] == PRISM2_TXFID_RESERVED)
2141 printk("Already reserved txfid found at idx "
2142 "%d\n", idx);
2143#endif
2144 local->intransmitfid[idx] = PRISM2_TXFID_EMPTY;
2145 idx++;
2146 local->next_alloc = idx >= PRISM2_TXFID_COUNT ? 0 :
2147 idx;
2148
2149 if (!test_bit(HOSTAP_BITS_TRANSMIT, &local->bits) &&
2150 netif_queue_stopped(dev))
2151 netif_wake_queue(dev);
2152
2153 spin_unlock(&local->txfidlock);
2154 return;
2155 }
2156
2157 idx++;
2158 if (idx >= PRISM2_TXFID_COUNT)
2159 idx = 0;
2160 } while (idx != local->next_alloc);
2161
2162 printk(KERN_WARNING "%s: could not find matching txfid (0x%04x, new "
2163 "read 0x%04x) for alloc event\n", dev->name, fid,
2164 HFA384X_INW(HFA384X_ALLOCFID_OFF));
2165 printk(KERN_DEBUG "TXFIDs:");
2166 for (idx = 0; idx < PRISM2_TXFID_COUNT; idx++)
2167 printk(" %04x[%04x]", local->txfid[idx],
2168 local->intransmitfid[idx]);
2169 printk("\n");
2170 spin_unlock(&local->txfidlock);
2171
2172 /* FIX: should probably schedule reset; reference to one txfid was lost
2173 * completely.. Bad things will happen if we run out of txfids
2174 * Actually, this will cause netdev watchdog to notice TX timeout and
2175 * then card reset after all txfids have been leaked. */
2176}
2177
2178
2179/* Called only as a tasklet (software IRQ) */
2180static void hostap_tx_callback(local_info_t *local,
2181 struct hfa384x_tx_frame *txdesc, int ok,
2182 char *payload)
2183{
2184 u16 sw_support, hdrlen, len;
2185 struct sk_buff *skb;
2186 struct hostap_tx_callback_info *cb;
2187
2188 /* Make sure that frame was from us. */
2189 if (memcmp(txdesc->addr2, local->dev->dev_addr, ETH_ALEN)) {
2190 printk(KERN_DEBUG "%s: TX callback - foreign frame\n",
2191 local->dev->name);
2192 return;
2193 }
2194
2195 sw_support = le16_to_cpu(txdesc->sw_support);
2196
2197 spin_lock(&local->lock);
2198 cb = local->tx_callback;
2199 while (cb != NULL && cb->idx != sw_support)
2200 cb = cb->next;
2201 spin_unlock(&local->lock);
2202
2203 if (cb == NULL) {
2204 printk(KERN_DEBUG "%s: could not find TX callback (idx %d)\n",
2205 local->dev->name, sw_support);
2206 return;
2207 }
2208
2209 hdrlen = hostap_80211_get_hdrlen(le16_to_cpu(txdesc->frame_control));
2210 len = le16_to_cpu(txdesc->data_len);
2211 skb = dev_alloc_skb(hdrlen + len);
2212 if (skb == NULL) {
2213 printk(KERN_DEBUG "%s: hostap_tx_callback failed to allocate "
2214 "skb\n", local->dev->name);
2215 return;
2216 }
2217
2218 memcpy(skb_put(skb, hdrlen), (void *) &txdesc->frame_control, hdrlen);
2219 if (payload)
2220 memcpy(skb_put(skb, len), payload, len);
2221
2222 skb->dev = local->dev;
2223 skb->mac.raw = skb->data;
2224
2225 cb->func(skb, ok, cb->data);
2226}
2227
2228
2229/* Called only as a tasklet (software IRQ) */
2230static int hostap_tx_compl_read(local_info_t *local, int error,
2231 struct hfa384x_tx_frame *txdesc,
2232 char **payload)
2233{
2234 u16 fid, len;
2235 int res, ret = 0;
2236 struct net_device *dev = local->dev;
2237
2238 fid = prism2_read_fid_reg(dev, HFA384X_TXCOMPLFID_OFF);
2239
2240 PDEBUG(DEBUG_FID, "interrupt: TX (err=%d) - fid=0x%04x\n", fid, error);
2241
2242 spin_lock(&local->baplock);
2243 res = hfa384x_setup_bap(dev, BAP0, fid, 0);
2244 if (!res)
2245 res = hfa384x_from_bap(dev, BAP0, txdesc, sizeof(*txdesc));
2246 if (res) {
2247 PDEBUG(DEBUG_EXTRA, "%s: TX (err=%d) - fid=0x%04x - could not "
2248 "read txdesc\n", dev->name, error, fid);
2249 if (res == -ETIMEDOUT) {
2250 schedule_work(&local->reset_queue);
2251 }
2252 ret = -1;
2253 goto fail;
2254 }
2255 if (txdesc->sw_support) {
2256 len = le16_to_cpu(txdesc->data_len);
2257 if (len < PRISM2_DATA_MAXLEN) {
2258 *payload = (char *) kmalloc(len, GFP_ATOMIC);
2259 if (*payload == NULL ||
2260 hfa384x_from_bap(dev, BAP0, *payload, len)) {
2261 PDEBUG(DEBUG_EXTRA, "%s: could not read TX "
2262 "frame payload\n", dev->name);
2263 kfree(*payload);
2264 *payload = NULL;
2265 ret = -1;
2266 goto fail;
2267 }
2268 }
2269 }
2270
2271 fail:
2272 spin_unlock(&local->baplock);
2273
2274 return ret;
2275}
2276
2277
2278/* Called only as a tasklet (software IRQ) */
2279static void prism2_tx_ev(local_info_t *local)
2280{
2281 struct net_device *dev = local->dev;
2282 char *payload = NULL;
2283 struct hfa384x_tx_frame txdesc;
2284
2285 if (hostap_tx_compl_read(local, 0, &txdesc, &payload))
2286 goto fail;
2287
2288 if (local->frame_dump & PRISM2_DUMP_TX_HDR) {
2289 PDEBUG(DEBUG_EXTRA, "%s: TX - status=0x%04x "
2290 "retry_count=%d tx_rate=%d seq_ctrl=%d "
2291 "duration_id=%d\n",
2292 dev->name, le16_to_cpu(txdesc.status),
2293 txdesc.retry_count, txdesc.tx_rate,
2294 le16_to_cpu(txdesc.seq_ctrl),
2295 le16_to_cpu(txdesc.duration_id));
2296 }
2297
2298 if (txdesc.sw_support)
2299 hostap_tx_callback(local, &txdesc, 1, payload);
2300 kfree(payload);
2301
2302 fail:
2303 HFA384X_OUTW(HFA384X_EV_TX, HFA384X_EVACK_OFF);
2304}
2305
2306
2307/* Called only as a tasklet (software IRQ) */
2308static void hostap_sta_tx_exc_tasklet(unsigned long data)
2309{
2310 local_info_t *local = (local_info_t *) data;
2311 struct sk_buff *skb;
2312
2313 while ((skb = skb_dequeue(&local->sta_tx_exc_list)) != NULL) {
2314 struct hfa384x_tx_frame *txdesc =
2315 (struct hfa384x_tx_frame *) skb->data;
2316
2317 if (skb->len >= sizeof(*txdesc)) {
2318 /* Convert Prism2 RX structure into IEEE 802.11 header
2319 */
2320 u16 fc = le16_to_cpu(txdesc->frame_control);
2321 int hdrlen = hostap_80211_get_hdrlen(fc);
2322 memmove(skb_pull(skb, sizeof(*txdesc) - hdrlen),
2323 &txdesc->frame_control, hdrlen);
2324
2325 hostap_handle_sta_tx_exc(local, skb);
2326 }
2327 dev_kfree_skb(skb);
2328 }
2329}
2330
2331
2332/* Called only as a tasklet (software IRQ) */
2333static void prism2_txexc(local_info_t *local)
2334{
2335 struct net_device *dev = local->dev;
2336 u16 status, fc;
2337 int show_dump, res;
2338 char *payload = NULL;
2339 struct hfa384x_tx_frame txdesc;
2340
2341 show_dump = local->frame_dump & PRISM2_DUMP_TXEXC_HDR;
2342 local->stats.tx_errors++;
2343
2344 res = hostap_tx_compl_read(local, 1, &txdesc, &payload);
2345 HFA384X_OUTW(HFA384X_EV_TXEXC, HFA384X_EVACK_OFF);
2346 if (res)
2347 return;
2348
2349 status = le16_to_cpu(txdesc.status);
2350
2351 /* We produce a TXDROP event only for retry or lifetime
2352 * exceeded, because that's the only status that really mean
2353 * that this particular node went away.
2354 * Other errors means that *we* screwed up. - Jean II */
2355 if (status & (HFA384X_TX_STATUS_RETRYERR | HFA384X_TX_STATUS_AGEDERR))
2356 {
2357 union iwreq_data wrqu;
2358
2359 /* Copy 802.11 dest address. */
2360 memcpy(wrqu.addr.sa_data, txdesc.addr1, ETH_ALEN);
2361 wrqu.addr.sa_family = ARPHRD_ETHER;
2362 wireless_send_event(dev, IWEVTXDROP, &wrqu, NULL);
2363 } else
2364 show_dump = 1;
2365
2366 if (local->iw_mode == IW_MODE_MASTER ||
2367 local->iw_mode == IW_MODE_REPEAT ||
2368 local->wds_type & HOSTAP_WDS_AP_CLIENT) {
2369 struct sk_buff *skb;
2370 skb = dev_alloc_skb(sizeof(txdesc));
2371 if (skb) {
2372 memcpy(skb_put(skb, sizeof(txdesc)), &txdesc,
2373 sizeof(txdesc));
2374 skb_queue_tail(&local->sta_tx_exc_list, skb);
2375 tasklet_schedule(&local->sta_tx_exc_tasklet);
2376 }
2377 }
2378
2379 if (txdesc.sw_support)
2380 hostap_tx_callback(local, &txdesc, 0, payload);
2381 kfree(payload);
2382
2383 if (!show_dump)
2384 return;
2385
2386 PDEBUG(DEBUG_EXTRA, "%s: TXEXC - status=0x%04x (%s%s%s%s)"
2387 " tx_control=%04x\n",
2388 dev->name, status,
2389 status & HFA384X_TX_STATUS_RETRYERR ? "[RetryErr]" : "",
2390 status & HFA384X_TX_STATUS_AGEDERR ? "[AgedErr]" : "",
2391 status & HFA384X_TX_STATUS_DISCON ? "[Discon]" : "",
2392 status & HFA384X_TX_STATUS_FORMERR ? "[FormErr]" : "",
2393 le16_to_cpu(txdesc.tx_control));
2394
2395 fc = le16_to_cpu(txdesc.frame_control);
2396 PDEBUG(DEBUG_EXTRA, " retry_count=%d tx_rate=%d fc=0x%04x "
2397 "(%s%s%s::%d%s%s)\n",
2398 txdesc.retry_count, txdesc.tx_rate, fc,
2399 WLAN_FC_GET_TYPE(fc) == IEEE80211_FTYPE_MGMT ? "Mgmt" : "",
2400 WLAN_FC_GET_TYPE(fc) == IEEE80211_FTYPE_CTL ? "Ctrl" : "",
2401 WLAN_FC_GET_TYPE(fc) == IEEE80211_FTYPE_DATA ? "Data" : "",
2402 WLAN_FC_GET_STYPE(fc) >> 4,
2403 fc & IEEE80211_FCTL_TODS ? " ToDS" : "",
2404 fc & IEEE80211_FCTL_FROMDS ? " FromDS" : "");
2405 PDEBUG(DEBUG_EXTRA, " A1=" MACSTR " A2=" MACSTR " A3="
2406 MACSTR " A4=" MACSTR "\n",
2407 MAC2STR(txdesc.addr1), MAC2STR(txdesc.addr2),
2408 MAC2STR(txdesc.addr3), MAC2STR(txdesc.addr4));
2409}
2410
2411
2412/* Called only as a tasklet (software IRQ) */
2413static void hostap_info_tasklet(unsigned long data)
2414{
2415 local_info_t *local = (local_info_t *) data;
2416 struct sk_buff *skb;
2417
2418 while ((skb = skb_dequeue(&local->info_list)) != NULL) {
2419 hostap_info_process(local, skb);
2420 dev_kfree_skb(skb);
2421 }
2422}
2423
2424
2425/* Called only as a tasklet (software IRQ) */
2426static void prism2_info(local_info_t *local)
2427{
2428 struct net_device *dev = local->dev;
2429 u16 fid;
2430 int res, left;
2431 struct hfa384x_info_frame info;
2432 struct sk_buff *skb;
2433
2434 fid = HFA384X_INW(HFA384X_INFOFID_OFF);
2435
2436 spin_lock(&local->baplock);
2437 res = hfa384x_setup_bap(dev, BAP0, fid, 0);
2438 if (!res)
2439 res = hfa384x_from_bap(dev, BAP0, &info, sizeof(info));
2440 if (res) {
2441 spin_unlock(&local->baplock);
2442 printk(KERN_DEBUG "Could not get info frame (fid=0x%04x)\n",
2443 fid);
2444 if (res == -ETIMEDOUT) {
2445 schedule_work(&local->reset_queue);
2446 }
2447 goto out;
2448 }
2449
2450 le16_to_cpus(&info.len);
2451 le16_to_cpus(&info.type);
2452 left = (info.len - 1) * 2;
2453
2454 if (info.len & 0x8000 || info.len == 0 || left > 2060) {
2455 /* data register seems to give 0x8000 in some error cases even
2456 * though busy bit is not set in offset register;
2457 * in addition, length must be at least 1 due to type field */
2458 spin_unlock(&local->baplock);
2459 printk(KERN_DEBUG "%s: Received info frame with invalid "
2460 "length 0x%04x (type 0x%04x)\n", dev->name, info.len,
2461 info.type);
2462 goto out;
2463 }
2464
2465 skb = dev_alloc_skb(sizeof(info) + left);
2466 if (skb == NULL) {
2467 spin_unlock(&local->baplock);
2468 printk(KERN_DEBUG "%s: Could not allocate skb for info "
2469 "frame\n", dev->name);
2470 goto out;
2471 }
2472
2473 memcpy(skb_put(skb, sizeof(info)), &info, sizeof(info));
2474 if (left > 0 && hfa384x_from_bap(dev, BAP0, skb_put(skb, left), left))
2475 {
2476 spin_unlock(&local->baplock);
2477 printk(KERN_WARNING "%s: Info frame read failed (fid=0x%04x, "
2478 "len=0x%04x, type=0x%04x\n",
2479 dev->name, fid, info.len, info.type);
2480 dev_kfree_skb(skb);
2481 goto out;
2482 }
2483 spin_unlock(&local->baplock);
2484
2485 skb_queue_tail(&local->info_list, skb);
2486 tasklet_schedule(&local->info_tasklet);
2487
2488 out:
2489 HFA384X_OUTW(HFA384X_EV_INFO, HFA384X_EVACK_OFF);
2490}
2491
2492
2493/* Called only as a tasklet (software IRQ) */
2494static void hostap_bap_tasklet(unsigned long data)
2495{
2496 local_info_t *local = (local_info_t *) data;
2497 struct net_device *dev = local->dev;
2498 u16 ev;
2499 int frames = 30;
2500
2501 if (local->func->card_present && !local->func->card_present(local))
2502 return;
2503
2504 set_bit(HOSTAP_BITS_BAP_TASKLET, &local->bits);
2505
2506 /* Process all pending BAP events without generating new interrupts
2507 * for them */
2508 while (frames-- > 0) {
2509 ev = HFA384X_INW(HFA384X_EVSTAT_OFF);
2510 if (ev == 0xffff || !(ev & HFA384X_BAP0_EVENTS))
2511 break;
2512 if (ev & HFA384X_EV_RX)
2513 prism2_rx(local);
2514 if (ev & HFA384X_EV_INFO)
2515 prism2_info(local);
2516 if (ev & HFA384X_EV_TX)
2517 prism2_tx_ev(local);
2518 if (ev & HFA384X_EV_TXEXC)
2519 prism2_txexc(local);
2520 }
2521
2522 set_bit(HOSTAP_BITS_BAP_TASKLET2, &local->bits);
2523 clear_bit(HOSTAP_BITS_BAP_TASKLET, &local->bits);
2524
2525 /* Enable interrupts for new BAP events */
2526 hfa384x_events_all(dev);
2527 clear_bit(HOSTAP_BITS_BAP_TASKLET2, &local->bits);
2528}
2529
2530
2531/* Called only from hardware IRQ */
2532static void prism2_infdrop(struct net_device *dev)
2533{
2534 static unsigned long last_inquire = 0;
2535
2536 PDEBUG(DEBUG_EXTRA, "%s: INFDROP event\n", dev->name);
2537
2538 /* some firmware versions seem to get stuck with
2539 * full CommTallies in high traffic load cases; every
2540 * packet will then cause INFDROP event and CommTallies
2541 * info frame will not be sent automatically. Try to
2542 * get out of this state by inquiring CommTallies. */
2543 if (!last_inquire || time_after(jiffies, last_inquire + HZ)) {
2544 hfa384x_cmd_callback(dev, HFA384X_CMDCODE_INQUIRE,
2545 HFA384X_INFO_COMMTALLIES, NULL, 0);
2546 last_inquire = jiffies;
2547 }
2548}
2549
2550
2551/* Called only from hardware IRQ */
2552static void prism2_ev_tick(struct net_device *dev)
2553{
2554 struct hostap_interface *iface;
2555 local_info_t *local;
2556 u16 evstat, inten;
2557 static int prev_stuck = 0;
2558
2559 iface = netdev_priv(dev);
2560 local = iface->local;
2561
2562 if (time_after(jiffies, local->last_tick_timer + 5 * HZ) &&
2563 local->last_tick_timer) {
2564 evstat = HFA384X_INW(HFA384X_EVSTAT_OFF);
2565 inten = HFA384X_INW(HFA384X_INTEN_OFF);
2566 if (!prev_stuck) {
2567 printk(KERN_INFO "%s: SW TICK stuck? "
2568 "bits=0x%lx EvStat=%04x IntEn=%04x\n",
2569 dev->name, local->bits, evstat, inten);
2570 }
2571 local->sw_tick_stuck++;
2572 if ((evstat & HFA384X_BAP0_EVENTS) &&
2573 (inten & HFA384X_BAP0_EVENTS)) {
2574 printk(KERN_INFO "%s: trying to recover from IRQ "
2575 "hang\n", dev->name);
2576 hfa384x_events_no_bap0(dev);
2577 }
2578 prev_stuck = 1;
2579 } else
2580 prev_stuck = 0;
2581}
2582
2583
2584/* Called only from hardware IRQ */
2585static inline void prism2_check_magic(local_info_t *local)
2586{
2587 /* at least PCI Prism2.5 with bus mastering seems to sometimes
2588 * return 0x0000 in SWSUPPORT0 for unknown reason, but re-reading the
2589 * register once or twice seems to get the correct value.. PCI cards
2590 * cannot anyway be removed during normal operation, so there is not
2591 * really any need for this verification with them. */
2592
2593#ifndef PRISM2_PCI
2594#ifndef final_version
2595 static unsigned long last_magic_err = 0;
2596 struct net_device *dev = local->dev;
2597
2598 if (HFA384X_INW(HFA384X_SWSUPPORT0_OFF) != HFA384X_MAGIC) {
2599 if (!local->hw_ready)
2600 return;
2601 HFA384X_OUTW(0xffff, HFA384X_EVACK_OFF);
2602 if (time_after(jiffies, last_magic_err + 10 * HZ)) {
2603 printk("%s: Interrupt, but SWSUPPORT0 does not match: "
2604 "%04X != %04X - card removed?\n", dev->name,
2605 HFA384X_INW(HFA384X_SWSUPPORT0_OFF),
2606 HFA384X_MAGIC);
2607 last_magic_err = jiffies;
2608 } else if (net_ratelimit()) {
2609 printk(KERN_DEBUG "%s: interrupt - SWSUPPORT0=%04x "
2610 "MAGIC=%04x\n", dev->name,
2611 HFA384X_INW(HFA384X_SWSUPPORT0_OFF),
2612 HFA384X_MAGIC);
2613 }
2614 if (HFA384X_INW(HFA384X_SWSUPPORT0_OFF) != 0xffff)
2615 schedule_work(&local->reset_queue);
2616 return;
2617 }
2618#endif /* final_version */
2619#endif /* !PRISM2_PCI */
2620}
2621
2622
2623/* Called only from hardware IRQ */
2624static irqreturn_t prism2_interrupt(int irq, void *dev_id, struct pt_regs *regs)
2625{
2626 struct net_device *dev = (struct net_device *) dev_id;
2627 struct hostap_interface *iface;
2628 local_info_t *local;
2629 int events = 0;
2630 u16 ev;
2631
2632 iface = netdev_priv(dev);
2633 local = iface->local;
2634
2635 prism2_io_debug_add(dev, PRISM2_IO_DEBUG_CMD_INTERRUPT, 0, 0);
2636
2637 if (local->func->card_present && !local->func->card_present(local)) {
2638 if (net_ratelimit()) {
2639 printk(KERN_DEBUG "%s: Interrupt, but dev not OK\n",
2640 dev->name);
2641 }
2642 return IRQ_HANDLED;
2643 }
2644
2645 prism2_check_magic(local);
2646
2647 for (;;) {
2648 ev = HFA384X_INW(HFA384X_EVSTAT_OFF);
2649 if (ev == 0xffff) {
2650 if (local->shutdown)
2651 return IRQ_HANDLED;
2652 HFA384X_OUTW(0xffff, HFA384X_EVACK_OFF);
2653 printk(KERN_DEBUG "%s: prism2_interrupt: ev=0xffff\n",
2654 dev->name);
2655 return IRQ_HANDLED;
2656 }
2657
2658 ev &= HFA384X_INW(HFA384X_INTEN_OFF);
2659 if (ev == 0)
2660 break;
2661
2662 if (ev & HFA384X_EV_CMD) {
2663 prism2_cmd_ev(dev);
2664 }
2665
2666 /* Above events are needed even before hw is ready, but other
2667 * events should be skipped during initialization. This may
2668 * change for AllocEv if allocate_fid is implemented without
2669 * busy waiting. */
2670 if (!local->hw_ready || local->hw_resetting ||
2671 !local->dev_enabled) {
2672 ev = HFA384X_INW(HFA384X_EVSTAT_OFF);
2673 if (ev & HFA384X_EV_CMD)
2674 goto next_event;
2675 if ((ev & HFA384X_EVENT_MASK) == 0)
2676 return IRQ_HANDLED;
2677 if (local->dev_enabled && (ev & ~HFA384X_EV_TICK) &&
2678 net_ratelimit()) {
2679 printk(KERN_DEBUG "%s: prism2_interrupt: hw "
2680 "not ready; skipping events 0x%04x "
2681 "(IntEn=0x%04x)%s%s%s\n",
2682 dev->name, ev,
2683 HFA384X_INW(HFA384X_INTEN_OFF),
2684 !local->hw_ready ? " (!hw_ready)" : "",
2685 local->hw_resetting ?
2686 " (hw_resetting)" : "",
2687 !local->dev_enabled ?
2688 " (!dev_enabled)" : "");
2689 }
2690 HFA384X_OUTW(ev, HFA384X_EVACK_OFF);
2691 return IRQ_HANDLED;
2692 }
2693
2694 if (ev & HFA384X_EV_TICK) {
2695 prism2_ev_tick(dev);
2696 HFA384X_OUTW(HFA384X_EV_TICK, HFA384X_EVACK_OFF);
2697 }
2698
2699 if (ev & HFA384X_EV_ALLOC) {
2700 prism2_alloc_ev(dev);
2701 HFA384X_OUTW(HFA384X_EV_ALLOC, HFA384X_EVACK_OFF);
2702 }
2703
2704 /* Reading data from the card is quite time consuming, so do it
2705 * in tasklets. TX, TXEXC, RX, and INFO events will be ACKed
2706 * and unmasked after needed data has been read completely. */
2707 if (ev & HFA384X_BAP0_EVENTS) {
2708 hfa384x_events_no_bap0(dev);
2709 tasklet_schedule(&local->bap_tasklet);
2710 }
2711
2712#ifndef final_version
2713 if (ev & HFA384X_EV_WTERR) {
2714 PDEBUG(DEBUG_EXTRA, "%s: WTERR event\n", dev->name);
2715 HFA384X_OUTW(HFA384X_EV_WTERR, HFA384X_EVACK_OFF);
2716 }
2717#endif /* final_version */
2718
2719 if (ev & HFA384X_EV_INFDROP) {
2720 prism2_infdrop(dev);
2721 HFA384X_OUTW(HFA384X_EV_INFDROP, HFA384X_EVACK_OFF);
2722 }
2723
2724 next_event:
2725 events++;
2726 if (events >= PRISM2_MAX_INTERRUPT_EVENTS) {
2727 PDEBUG(DEBUG_EXTRA, "prism2_interrupt: >%d events "
2728 "(EvStat=0x%04x)\n",
2729 PRISM2_MAX_INTERRUPT_EVENTS,
2730 HFA384X_INW(HFA384X_EVSTAT_OFF));
2731 break;
2732 }
2733 }
2734 prism2_io_debug_add(dev, PRISM2_IO_DEBUG_CMD_INTERRUPT, 0, 1);
2735 return IRQ_RETVAL(events);
2736}
2737
2738
2739static void prism2_check_sta_fw_version(local_info_t *local)
2740{
2741 struct hfa384x_comp_ident comp;
2742 int id, variant, major, minor;
2743
2744 if (hfa384x_get_rid(local->dev, HFA384X_RID_STAID,
2745 &comp, sizeof(comp), 1) < 0)
2746 return;
2747
2748 local->fw_ap = 0;
2749 id = le16_to_cpu(comp.id);
2750 if (id != HFA384X_COMP_ID_STA) {
2751 if (id == HFA384X_COMP_ID_FW_AP)
2752 local->fw_ap = 1;
2753 return;
2754 }
2755
2756 major = __le16_to_cpu(comp.major);
2757 minor = __le16_to_cpu(comp.minor);
2758 variant = __le16_to_cpu(comp.variant);
2759 local->sta_fw_ver = PRISM2_FW_VER(major, minor, variant);
2760
2761 /* Station firmware versions before 1.4.x seem to have a bug in
2762 * firmware-based WEP encryption when using Host AP mode, so use
2763 * host_encrypt as a default for them. Firmware version 1.4.9 is the
2764 * first one that has been seen to produce correct encryption, but the
2765 * bug might be fixed before that (although, at least 1.4.2 is broken).
2766 */
2767 local->fw_encrypt_ok = local->sta_fw_ver >= PRISM2_FW_VER(1,4,9);
2768
2769 if (local->iw_mode == IW_MODE_MASTER && !local->host_encrypt &&
2770 !local->fw_encrypt_ok) {
2771 printk(KERN_DEBUG "%s: defaulting to host-based encryption as "
2772 "a workaround for firmware bug in Host AP mode WEP\n",
2773 local->dev->name);
2774 local->host_encrypt = 1;
2775 }
2776
2777 /* IEEE 802.11 standard compliant WDS frames (4 addresses) were broken
2778 * in station firmware versions before 1.5.x. With these versions, the
2779 * driver uses a workaround with bogus frame format (4th address after
2780 * the payload). This is not compatible with other AP devices. Since
2781 * the firmware bug is fixed in the latest station firmware versions,
2782 * automatically enable standard compliant mode for cards using station
2783 * firmware version 1.5.0 or newer. */
2784 if (local->sta_fw_ver >= PRISM2_FW_VER(1,5,0))
2785 local->wds_type |= HOSTAP_WDS_STANDARD_FRAME;
2786 else {
2787 printk(KERN_DEBUG "%s: defaulting to bogus WDS frame as a "
2788 "workaround for firmware bug in Host AP mode WDS\n",
2789 local->dev->name);
2790 }
2791
2792 hostap_check_sta_fw_version(local->ap, local->sta_fw_ver);
2793}
2794
2795
2796static void prism2_crypt_deinit_entries(local_info_t *local, int force)
2797{
2798 struct list_head *ptr, *n;
2799 struct ieee80211_crypt_data *entry;
2800
2801 for (ptr = local->crypt_deinit_list.next, n = ptr->next;
2802 ptr != &local->crypt_deinit_list; ptr = n, n = ptr->next) {
2803 entry = list_entry(ptr, struct ieee80211_crypt_data, list);
2804
2805 if (atomic_read(&entry->refcnt) != 0 && !force)
2806 continue;
2807
2808 list_del(ptr);
2809
2810 if (entry->ops)
2811 entry->ops->deinit(entry->priv);
2812 kfree(entry);
2813 }
2814}
2815
2816
2817static void prism2_crypt_deinit_handler(unsigned long data)
2818{
2819 local_info_t *local = (local_info_t *) data;
2820 unsigned long flags;
2821
2822 spin_lock_irqsave(&local->lock, flags);
2823 prism2_crypt_deinit_entries(local, 0);
2824 if (!list_empty(&local->crypt_deinit_list)) {
2825 printk(KERN_DEBUG "%s: entries remaining in delayed crypt "
2826 "deletion list\n", local->dev->name);
2827 local->crypt_deinit_timer.expires = jiffies + HZ;
2828 add_timer(&local->crypt_deinit_timer);
2829 }
2830 spin_unlock_irqrestore(&local->lock, flags);
2831
2832}
2833
2834
2835static void hostap_passive_scan(unsigned long data)
2836{
2837 local_info_t *local = (local_info_t *) data;
2838 struct net_device *dev = local->dev;
2839 u16 channel;
2840
2841 if (local->passive_scan_interval <= 0)
2842 return;
2843
2844 if (local->passive_scan_state == PASSIVE_SCAN_LISTEN) {
2845 int max_tries = 16;
2846
2847 /* Even though host system does not really know when the WLAN
2848 * MAC is sending frames, try to avoid changing channels for
2849 * passive scanning when a host-generated frame is being
2850 * transmitted */
2851 if (test_bit(HOSTAP_BITS_TRANSMIT, &local->bits)) {
2852 printk(KERN_DEBUG "%s: passive scan detected pending "
2853 "TX - delaying\n", dev->name);
2854 local->passive_scan_timer.expires = jiffies + HZ / 10;
2855 add_timer(&local->passive_scan_timer);
2856 return;
2857 }
2858
2859 do {
2860 local->passive_scan_channel++;
2861 if (local->passive_scan_channel > 14)
2862 local->passive_scan_channel = 1;
2863 max_tries--;
2864 } while (!(local->channel_mask &
2865 (1 << (local->passive_scan_channel - 1))) &&
2866 max_tries > 0);
2867
2868 if (max_tries == 0) {
2869 printk(KERN_INFO "%s: no allowed passive scan channels"
2870 " found\n", dev->name);
2871 return;
2872 }
2873
2874 printk(KERN_DEBUG "%s: passive scan channel %d\n",
2875 dev->name, local->passive_scan_channel);
2876 channel = local->passive_scan_channel;
2877 local->passive_scan_state = PASSIVE_SCAN_WAIT;
2878 local->passive_scan_timer.expires = jiffies + HZ / 10;
2879 } else {
2880 channel = local->channel;
2881 local->passive_scan_state = PASSIVE_SCAN_LISTEN;
2882 local->passive_scan_timer.expires = jiffies +
2883 local->passive_scan_interval * HZ;
2884 }
2885
2886 if (hfa384x_cmd_callback(dev, HFA384X_CMDCODE_TEST |
2887 (HFA384X_TEST_CHANGE_CHANNEL << 8),
2888 channel, NULL, 0))
2889 printk(KERN_ERR "%s: passive scan channel set %d "
2890 "failed\n", dev->name, channel);
2891
2892 add_timer(&local->passive_scan_timer);
2893}
2894
2895
2896/* Called only as a scheduled task when communications quality values should
2897 * be updated. */
2898static void handle_comms_qual_update(void *data)
2899{
2900 local_info_t *local = data;
2901 prism2_update_comms_qual(local->dev);
2902}
2903
2904
2905/* Software watchdog - called as a timer. Hardware interrupt (Tick event) is
2906 * used to monitor that local->last_tick_timer is being updated. If not,
2907 * interrupt busy-loop is assumed and driver tries to recover by masking out
2908 * some events. */
2909static void hostap_tick_timer(unsigned long data)
2910{
2911 static unsigned long last_inquire = 0;
2912 local_info_t *local = (local_info_t *) data;
2913 local->last_tick_timer = jiffies;
2914
2915 /* Inquire CommTallies every 10 seconds to keep the statistics updated
2916 * more often during low load and when using 32-bit tallies. */
2917 if ((!last_inquire || time_after(jiffies, last_inquire + 10 * HZ)) &&
2918 !local->hw_downloading && local->hw_ready &&
2919 !local->hw_resetting && local->dev_enabled) {
2920 hfa384x_cmd_callback(local->dev, HFA384X_CMDCODE_INQUIRE,
2921 HFA384X_INFO_COMMTALLIES, NULL, 0);
2922 last_inquire = jiffies;
2923 }
2924
2925 if ((local->last_comms_qual_update == 0 ||
2926 time_after(jiffies, local->last_comms_qual_update + 10 * HZ)) &&
2927 (local->iw_mode == IW_MODE_INFRA ||
2928 local->iw_mode == IW_MODE_ADHOC)) {
2929 schedule_work(&local->comms_qual_update);
2930 }
2931
2932 local->tick_timer.expires = jiffies + 2 * HZ;
2933 add_timer(&local->tick_timer);
2934}
2935
2936
2937#ifndef PRISM2_NO_PROCFS_DEBUG
2938static int prism2_registers_proc_read(char *page, char **start, off_t off,
2939 int count, int *eof, void *data)
2940{
2941 char *p = page;
2942 local_info_t *local = (local_info_t *) data;
2943
2944 if (off != 0) {
2945 *eof = 1;
2946 return 0;
2947 }
2948
2949#define SHOW_REG(n) \
2950p += sprintf(p, #n "=%04x\n", hfa384x_read_reg(local->dev, HFA384X_##n##_OFF))
2951
2952 SHOW_REG(CMD);
2953 SHOW_REG(PARAM0);
2954 SHOW_REG(PARAM1);
2955 SHOW_REG(PARAM2);
2956 SHOW_REG(STATUS);
2957 SHOW_REG(RESP0);
2958 SHOW_REG(RESP1);
2959 SHOW_REG(RESP2);
2960 SHOW_REG(INFOFID);
2961 SHOW_REG(CONTROL);
2962 SHOW_REG(SELECT0);
2963 SHOW_REG(SELECT1);
2964 SHOW_REG(OFFSET0);
2965 SHOW_REG(OFFSET1);
2966 SHOW_REG(RXFID);
2967 SHOW_REG(ALLOCFID);
2968 SHOW_REG(TXCOMPLFID);
2969 SHOW_REG(SWSUPPORT0);
2970 SHOW_REG(SWSUPPORT1);
2971 SHOW_REG(SWSUPPORT2);
2972 SHOW_REG(EVSTAT);
2973 SHOW_REG(INTEN);
2974 SHOW_REG(EVACK);
2975 /* Do not read data registers, because they change the state of the
2976 * MAC (offset += 2) */
2977 /* SHOW_REG(DATA0); */
2978 /* SHOW_REG(DATA1); */
2979 SHOW_REG(AUXPAGE);
2980 SHOW_REG(AUXOFFSET);
2981 /* SHOW_REG(AUXDATA); */
2982#ifdef PRISM2_PCI
2983 SHOW_REG(PCICOR);
2984 SHOW_REG(PCIHCR);
2985 SHOW_REG(PCI_M0_ADDRH);
2986 SHOW_REG(PCI_M0_ADDRL);
2987 SHOW_REG(PCI_M0_LEN);
2988 SHOW_REG(PCI_M0_CTL);
2989 SHOW_REG(PCI_STATUS);
2990 SHOW_REG(PCI_M1_ADDRH);
2991 SHOW_REG(PCI_M1_ADDRL);
2992 SHOW_REG(PCI_M1_LEN);
2993 SHOW_REG(PCI_M1_CTL);
2994#endif /* PRISM2_PCI */
2995
2996 return (p - page);
2997}
2998#endif /* PRISM2_NO_PROCFS_DEBUG */
2999
3000
3001struct set_tim_data {
3002 struct list_head list;
3003 int aid;
3004 int set;
3005};
3006
3007static int prism2_set_tim(struct net_device *dev, int aid, int set)
3008{
3009 struct list_head *ptr;
3010 struct set_tim_data *new_entry;
3011 struct hostap_interface *iface;
3012 local_info_t *local;
3013
3014 iface = netdev_priv(dev);
3015 local = iface->local;
3016
3017 new_entry = (struct set_tim_data *)
3018 kmalloc(sizeof(*new_entry), GFP_ATOMIC);
3019 if (new_entry == NULL) {
3020 printk(KERN_DEBUG "%s: prism2_set_tim: kmalloc failed\n",
3021 local->dev->name);
3022 return -ENOMEM;
3023 }
3024 memset(new_entry, 0, sizeof(*new_entry));
3025 new_entry->aid = aid;
3026 new_entry->set = set;
3027
3028 spin_lock_bh(&local->set_tim_lock);
3029 list_for_each(ptr, &local->set_tim_list) {
3030 struct set_tim_data *entry =
3031 list_entry(ptr, struct set_tim_data, list);
3032 if (entry->aid == aid) {
3033 PDEBUG(DEBUG_PS2, "%s: prism2_set_tim: aid=%d "
3034 "set=%d ==> %d\n",
3035 local->dev->name, aid, entry->set, set);
3036 entry->set = set;
3037 kfree(new_entry);
3038 new_entry = NULL;
3039 break;
3040 }
3041 }
3042 if (new_entry)
3043 list_add_tail(&new_entry->list, &local->set_tim_list);
3044 spin_unlock_bh(&local->set_tim_lock);
3045
3046 schedule_work(&local->set_tim_queue);
3047
3048 return 0;
3049}
3050
3051
3052static void handle_set_tim_queue(void *data)
3053{
3054 local_info_t *local = (local_info_t *) data;
3055 struct set_tim_data *entry;
3056 u16 val;
3057
3058 for (;;) {
3059 entry = NULL;
3060 spin_lock_bh(&local->set_tim_lock);
3061 if (!list_empty(&local->set_tim_list)) {
3062 entry = list_entry(local->set_tim_list.next,
3063 struct set_tim_data, list);
3064 list_del(&entry->list);
3065 }
3066 spin_unlock_bh(&local->set_tim_lock);
3067 if (!entry)
3068 break;
3069
3070 PDEBUG(DEBUG_PS2, "%s: handle_set_tim_queue: aid=%d set=%d\n",
3071 local->dev->name, entry->aid, entry->set);
3072
3073 val = entry->aid;
3074 if (entry->set)
3075 val |= 0x8000;
3076 if (hostap_set_word(local->dev, HFA384X_RID_CNFTIMCTRL, val)) {
3077 printk(KERN_DEBUG "%s: set_tim failed (aid=%d "
3078 "set=%d)\n",
3079 local->dev->name, entry->aid, entry->set);
3080 }
3081
3082 kfree(entry);
3083 }
3084}
3085
3086
3087static void prism2_clear_set_tim_queue(local_info_t *local)
3088{
3089 struct list_head *ptr, *n;
3090
3091 list_for_each_safe(ptr, n, &local->set_tim_list) {
3092 struct set_tim_data *entry;
3093 entry = list_entry(ptr, struct set_tim_data, list);
3094 list_del(&entry->list);
3095 kfree(entry);
3096 }
3097}
3098
3099
3100static struct net_device *
3101prism2_init_local_data(struct prism2_helper_functions *funcs, int card_idx,
3102 struct device *sdev)
3103{
3104 struct net_device *dev;
3105 struct hostap_interface *iface;
3106 struct local_info *local;
3107 int len, i, ret;
3108
3109 if (funcs == NULL)
3110 return NULL;
3111
3112 len = strlen(dev_template);
3113 if (len >= IFNAMSIZ || strstr(dev_template, "%d") == NULL) {
3114 printk(KERN_WARNING "hostap: Invalid dev_template='%s'\n",
3115 dev_template);
3116 return NULL;
3117 }
3118
3119 len = sizeof(struct hostap_interface) +
3120 3 + sizeof(struct local_info) +
3121 3 + sizeof(struct ap_data);
3122
3123 dev = alloc_etherdev(len);
3124 if (dev == NULL)
3125 return NULL;
3126
3127 iface = netdev_priv(dev);
3128 local = (struct local_info *) ((((long) (iface + 1)) + 3) & ~3);
3129 local->ap = (struct ap_data *) ((((long) (local + 1)) + 3) & ~3);
3130 local->dev = iface->dev = dev;
3131 iface->local = local;
3132 iface->type = HOSTAP_INTERFACE_MASTER;
3133 INIT_LIST_HEAD(&local->hostap_interfaces);
3134
3135 local->hw_module = THIS_MODULE;
3136
3137#ifdef PRISM2_IO_DEBUG
3138 local->io_debug_enabled = 1;
3139#endif /* PRISM2_IO_DEBUG */
3140
3141 local->func = funcs;
3142 local->func->cmd = hfa384x_cmd;
3143 local->func->read_regs = hfa384x_read_regs;
3144 local->func->get_rid = hfa384x_get_rid;
3145 local->func->set_rid = hfa384x_set_rid;
3146 local->func->hw_enable = prism2_hw_enable;
3147 local->func->hw_config = prism2_hw_config;
3148 local->func->hw_reset = prism2_hw_reset;
3149 local->func->hw_shutdown = prism2_hw_shutdown;
3150 local->func->reset_port = prism2_reset_port;
3151 local->func->schedule_reset = prism2_schedule_reset;
3152#ifdef PRISM2_DOWNLOAD_SUPPORT
3153 local->func->read_aux = prism2_download_aux_dump;
3154 local->func->download = prism2_download;
3155#endif /* PRISM2_DOWNLOAD_SUPPORT */
3156 local->func->tx = prism2_tx_80211;
3157 local->func->set_tim = prism2_set_tim;
3158 local->func->need_tx_headroom = 0; /* no need to add txdesc in
3159 * skb->data (FIX: maybe for DMA bus
3160 * mastering? */
3161
3162 local->mtu = mtu;
3163
3164 rwlock_init(&local->iface_lock);
3165 spin_lock_init(&local->txfidlock);
3166 spin_lock_init(&local->cmdlock);
3167 spin_lock_init(&local->baplock);
3168 spin_lock_init(&local->lock);
3169 init_MUTEX(&local->rid_bap_sem);
3170
3171 if (card_idx < 0 || card_idx >= MAX_PARM_DEVICES)
3172 card_idx = 0;
3173 local->card_idx = card_idx;
3174
3175 len = strlen(essid);
3176 memcpy(local->essid, essid,
3177 len > MAX_SSID_LEN ? MAX_SSID_LEN : len);
3178 local->essid[MAX_SSID_LEN] = '\0';
3179 i = GET_INT_PARM(iw_mode, card_idx);
3180 if ((i >= IW_MODE_ADHOC && i <= IW_MODE_REPEAT) ||
3181 i == IW_MODE_MONITOR) {
3182 local->iw_mode = i;
3183 } else {
3184 printk(KERN_WARNING "prism2: Unknown iw_mode %d; using "
3185 "IW_MODE_MASTER\n", i);
3186 local->iw_mode = IW_MODE_MASTER;
3187 }
3188 local->channel = GET_INT_PARM(channel, card_idx);
3189 local->beacon_int = GET_INT_PARM(beacon_int, card_idx);
3190 local->dtim_period = GET_INT_PARM(dtim_period, card_idx);
3191 local->wds_max_connections = 16;
3192 local->tx_control = HFA384X_TX_CTRL_FLAGS;
3193 local->manual_retry_count = -1;
3194 local->rts_threshold = 2347;
3195 local->fragm_threshold = 2346;
3196 local->rssi_to_dBm = 100; /* default; to be overriden by
3197 * cnfDbmAdjust, if available */
3198 local->auth_algs = PRISM2_AUTH_OPEN | PRISM2_AUTH_SHARED_KEY;
3199 local->sram_type = -1;
3200 local->scan_channel_mask = 0xffff;
3201
3202 /* Initialize task queue structures */
3203 INIT_WORK(&local->reset_queue, handle_reset_queue, local);
3204 INIT_WORK(&local->set_multicast_list_queue,
3205 hostap_set_multicast_list_queue, local->dev);
3206
3207 INIT_WORK(&local->set_tim_queue, handle_set_tim_queue, local);
3208 INIT_LIST_HEAD(&local->set_tim_list);
3209 spin_lock_init(&local->set_tim_lock);
3210
3211 INIT_WORK(&local->comms_qual_update, handle_comms_qual_update, local);
3212
3213 /* Initialize tasklets for handling hardware IRQ related operations
3214 * outside hw IRQ handler */
3215#define HOSTAP_TASKLET_INIT(q, f, d) \
3216do { memset((q), 0, sizeof(*(q))); (q)->func = (f); (q)->data = (d); } \
3217while (0)
3218 HOSTAP_TASKLET_INIT(&local->bap_tasklet, hostap_bap_tasklet,
3219 (unsigned long) local);
3220
3221 HOSTAP_TASKLET_INIT(&local->info_tasklet, hostap_info_tasklet,
3222 (unsigned long) local);
3223 hostap_info_init(local);
3224
3225 HOSTAP_TASKLET_INIT(&local->rx_tasklet,
3226 hostap_rx_tasklet, (unsigned long) local);
3227 skb_queue_head_init(&local->rx_list);
3228
3229 HOSTAP_TASKLET_INIT(&local->sta_tx_exc_tasklet,
3230 hostap_sta_tx_exc_tasklet, (unsigned long) local);
3231 skb_queue_head_init(&local->sta_tx_exc_list);
3232
3233 INIT_LIST_HEAD(&local->cmd_queue);
3234 init_waitqueue_head(&local->hostscan_wq);
3235 INIT_LIST_HEAD(&local->crypt_deinit_list);
3236 init_timer(&local->crypt_deinit_timer);
3237 local->crypt_deinit_timer.data = (unsigned long) local;
3238 local->crypt_deinit_timer.function = prism2_crypt_deinit_handler;
3239
3240 init_timer(&local->passive_scan_timer);
3241 local->passive_scan_timer.data = (unsigned long) local;
3242 local->passive_scan_timer.function = hostap_passive_scan;
3243
3244 init_timer(&local->tick_timer);
3245 local->tick_timer.data = (unsigned long) local;
3246 local->tick_timer.function = hostap_tick_timer;
3247 local->tick_timer.expires = jiffies + 2 * HZ;
3248 add_timer(&local->tick_timer);
3249
3250 INIT_LIST_HEAD(&local->bss_list);
3251
3252 hostap_setup_dev(dev, local, 1);
3253 local->saved_eth_header_parse = dev->hard_header_parse;
3254
3255 dev->hard_start_xmit = hostap_master_start_xmit;
3256 dev->type = ARPHRD_IEEE80211;
3257 dev->hard_header_parse = hostap_80211_header_parse;
3258
3259 rtnl_lock();
3260 ret = dev_alloc_name(dev, "wifi%d");
3261 SET_NETDEV_DEV(dev, sdev);
3262 if (ret >= 0)
3263 ret = register_netdevice(dev);
3264 rtnl_unlock();
3265 if (ret < 0) {
3266 printk(KERN_WARNING "%s: register netdevice failed!\n",
3267 dev_info);
3268 goto fail;
3269 }
3270 printk(KERN_INFO "%s: Registered netdevice %s\n", dev_info, dev->name);
3271
3272#ifndef PRISM2_NO_PROCFS_DEBUG
3273 create_proc_read_entry("registers", 0, local->proc,
3274 prism2_registers_proc_read, local);
3275#endif /* PRISM2_NO_PROCFS_DEBUG */
3276
3277 hostap_init_data(local);
3278 return dev;
3279
3280 fail:
3281 free_netdev(dev);
3282 return NULL;
3283}
3284
3285
3286static int hostap_hw_ready(struct net_device *dev)
3287{
3288 struct hostap_interface *iface;
3289 struct local_info *local;
3290
3291 iface = netdev_priv(dev);
3292 local = iface->local;
3293 local->ddev = hostap_add_interface(local, HOSTAP_INTERFACE_MAIN, 0,
3294 "", dev_template);
3295
3296 if (local->ddev) {
3297 if (local->iw_mode == IW_MODE_INFRA ||
3298 local->iw_mode == IW_MODE_ADHOC) {
3299 netif_carrier_off(local->dev);
3300 netif_carrier_off(local->ddev);
3301 }
3302 hostap_init_proc(local);
3303 hostap_init_ap_proc(local);
3304 return 0;
3305 }
3306
3307 return -1;
3308}
3309
3310
3311static void prism2_free_local_data(struct net_device *dev)
3312{
3313 struct hostap_tx_callback_info *tx_cb, *tx_cb_prev;
3314 int i;
3315 struct hostap_interface *iface;
3316 struct local_info *local;
3317 struct list_head *ptr, *n;
3318
3319 if (dev == NULL)
3320 return;
3321
3322 iface = netdev_priv(dev);
3323 local = iface->local;
3324
3325 flush_scheduled_work();
3326
3327 if (timer_pending(&local->crypt_deinit_timer))
3328 del_timer(&local->crypt_deinit_timer);
3329 prism2_crypt_deinit_entries(local, 1);
3330
3331 if (timer_pending(&local->passive_scan_timer))
3332 del_timer(&local->passive_scan_timer);
3333
3334 if (timer_pending(&local->tick_timer))
3335 del_timer(&local->tick_timer);
3336
3337 prism2_clear_cmd_queue(local);
3338
3339 skb_queue_purge(&local->info_list);
3340 skb_queue_purge(&local->rx_list);
3341 skb_queue_purge(&local->sta_tx_exc_list);
3342
3343 if (local->dev_enabled)
3344 prism2_callback(local, PRISM2_CALLBACK_DISABLE);
3345
3346 for (i = 0; i < WEP_KEYS; i++) {
3347 struct ieee80211_crypt_data *crypt = local->crypt[i];
3348 if (crypt) {
3349 if (crypt->ops)
3350 crypt->ops->deinit(crypt->priv);
3351 kfree(crypt);
3352 local->crypt[i] = NULL;
3353 }
3354 }
3355
3356 if (local->ap != NULL)
3357 hostap_free_data(local->ap);
3358
3359#ifndef PRISM2_NO_PROCFS_DEBUG
3360 if (local->proc != NULL)
3361 remove_proc_entry("registers", local->proc);
3362#endif /* PRISM2_NO_PROCFS_DEBUG */
3363 hostap_remove_proc(local);
3364
3365 tx_cb = local->tx_callback;
3366 while (tx_cb != NULL) {
3367 tx_cb_prev = tx_cb;
3368 tx_cb = tx_cb->next;
3369 kfree(tx_cb_prev);
3370 }
3371
3372 hostap_set_hostapd(local, 0, 0);
3373 hostap_set_hostapd_sta(local, 0, 0);
3374
3375 for (i = 0; i < PRISM2_FRAG_CACHE_LEN; i++) {
3376 if (local->frag_cache[i].skb != NULL)
3377 dev_kfree_skb(local->frag_cache[i].skb);
3378 }
3379
3380#ifdef PRISM2_DOWNLOAD_SUPPORT
3381 prism2_download_free_data(local->dl_pri);
3382 prism2_download_free_data(local->dl_sec);
3383#endif /* PRISM2_DOWNLOAD_SUPPORT */
3384
3385 list_for_each_safe(ptr, n, &local->hostap_interfaces) {
3386 iface = list_entry(ptr, struct hostap_interface, list);
3387 if (iface->type == HOSTAP_INTERFACE_MASTER) {
3388 /* special handling for this interface below */
3389 continue;
3390 }
3391 hostap_remove_interface(iface->dev, 0, 1);
3392 }
3393
3394 prism2_clear_set_tim_queue(local);
3395
3396 list_for_each_safe(ptr, n, &local->bss_list) {
3397 struct hostap_bss_info *bss =
3398 list_entry(ptr, struct hostap_bss_info, list);
3399 kfree(bss);
3400 }
3401
3402 kfree(local->pda);
3403 kfree(local->last_scan_results);
3404 kfree(local->generic_elem);
3405
3406 unregister_netdev(local->dev);
3407 free_netdev(local->dev);
3408}
3409
3410
3411#ifndef PRISM2_PLX
3412static void prism2_suspend(struct net_device *dev)
3413{
3414 struct hostap_interface *iface;
3415 struct local_info *local;
3416 union iwreq_data wrqu;
3417
3418 iface = dev->priv;
3419 local = iface->local;
3420
3421 /* Send disconnect event, e.g., to trigger reassociation after resume
3422 * if wpa_supplicant is used. */
3423 memset(&wrqu, 0, sizeof(wrqu));
3424 wrqu.ap_addr.sa_family = ARPHRD_ETHER;
3425 wireless_send_event(local->dev, SIOCGIWAP, &wrqu, NULL);
3426
3427 /* Disable hardware and firmware */
3428 prism2_hw_shutdown(dev, 0);
3429}
3430#endif /* PRISM2_PLX */
3431
3432
3433/* These might at some point be compiled separately and used as separate
3434 * kernel modules or linked into one */
3435#ifdef PRISM2_DOWNLOAD_SUPPORT
3436#include "hostap_download.c"
3437#endif /* PRISM2_DOWNLOAD_SUPPORT */
3438
3439#ifdef PRISM2_CALLBACK
3440/* External hostap_callback.c file can be used to, e.g., blink activity led.
3441 * This can use platform specific code and must define prism2_callback()
3442 * function (if PRISM2_CALLBACK is not defined, these function calls are not
3443 * used. */
3444#include "hostap_callback.c"
3445#endif /* PRISM2_CALLBACK */
diff --git a/drivers/net/wireless/hostap/hostap_info.c b/drivers/net/wireless/hostap/hostap_info.c
new file mode 100644
index 000000000000..5aa998fdf1c4
--- /dev/null
+++ b/drivers/net/wireless/hostap/hostap_info.c
@@ -0,0 +1,499 @@
1/* Host AP driver Info Frame processing (part of hostap.o module) */
2
3
4/* Called only as a tasklet (software IRQ) */
5static void prism2_info_commtallies16(local_info_t *local, unsigned char *buf,
6 int left)
7{
8 struct hfa384x_comm_tallies *tallies;
9
10 if (left < sizeof(struct hfa384x_comm_tallies)) {
11 printk(KERN_DEBUG "%s: too short (len=%d) commtallies "
12 "info frame\n", local->dev->name, left);
13 return;
14 }
15
16 tallies = (struct hfa384x_comm_tallies *) buf;
17#define ADD_COMM_TALLIES(name) \
18local->comm_tallies.name += le16_to_cpu(tallies->name)
19 ADD_COMM_TALLIES(tx_unicast_frames);
20 ADD_COMM_TALLIES(tx_multicast_frames);
21 ADD_COMM_TALLIES(tx_fragments);
22 ADD_COMM_TALLIES(tx_unicast_octets);
23 ADD_COMM_TALLIES(tx_multicast_octets);
24 ADD_COMM_TALLIES(tx_deferred_transmissions);
25 ADD_COMM_TALLIES(tx_single_retry_frames);
26 ADD_COMM_TALLIES(tx_multiple_retry_frames);
27 ADD_COMM_TALLIES(tx_retry_limit_exceeded);
28 ADD_COMM_TALLIES(tx_discards);
29 ADD_COMM_TALLIES(rx_unicast_frames);
30 ADD_COMM_TALLIES(rx_multicast_frames);
31 ADD_COMM_TALLIES(rx_fragments);
32 ADD_COMM_TALLIES(rx_unicast_octets);
33 ADD_COMM_TALLIES(rx_multicast_octets);
34 ADD_COMM_TALLIES(rx_fcs_errors);
35 ADD_COMM_TALLIES(rx_discards_no_buffer);
36 ADD_COMM_TALLIES(tx_discards_wrong_sa);
37 ADD_COMM_TALLIES(rx_discards_wep_undecryptable);
38 ADD_COMM_TALLIES(rx_message_in_msg_fragments);
39 ADD_COMM_TALLIES(rx_message_in_bad_msg_fragments);
40#undef ADD_COMM_TALLIES
41}
42
43
44/* Called only as a tasklet (software IRQ) */
45static void prism2_info_commtallies32(local_info_t *local, unsigned char *buf,
46 int left)
47{
48 struct hfa384x_comm_tallies32 *tallies;
49
50 if (left < sizeof(struct hfa384x_comm_tallies32)) {
51 printk(KERN_DEBUG "%s: too short (len=%d) commtallies32 "
52 "info frame\n", local->dev->name, left);
53 return;
54 }
55
56 tallies = (struct hfa384x_comm_tallies32 *) buf;
57#define ADD_COMM_TALLIES(name) \
58local->comm_tallies.name += le32_to_cpu(tallies->name)
59 ADD_COMM_TALLIES(tx_unicast_frames);
60 ADD_COMM_TALLIES(tx_multicast_frames);
61 ADD_COMM_TALLIES(tx_fragments);
62 ADD_COMM_TALLIES(tx_unicast_octets);
63 ADD_COMM_TALLIES(tx_multicast_octets);
64 ADD_COMM_TALLIES(tx_deferred_transmissions);
65 ADD_COMM_TALLIES(tx_single_retry_frames);
66 ADD_COMM_TALLIES(tx_multiple_retry_frames);
67 ADD_COMM_TALLIES(tx_retry_limit_exceeded);
68 ADD_COMM_TALLIES(tx_discards);
69 ADD_COMM_TALLIES(rx_unicast_frames);
70 ADD_COMM_TALLIES(rx_multicast_frames);
71 ADD_COMM_TALLIES(rx_fragments);
72 ADD_COMM_TALLIES(rx_unicast_octets);
73 ADD_COMM_TALLIES(rx_multicast_octets);
74 ADD_COMM_TALLIES(rx_fcs_errors);
75 ADD_COMM_TALLIES(rx_discards_no_buffer);
76 ADD_COMM_TALLIES(tx_discards_wrong_sa);
77 ADD_COMM_TALLIES(rx_discards_wep_undecryptable);
78 ADD_COMM_TALLIES(rx_message_in_msg_fragments);
79 ADD_COMM_TALLIES(rx_message_in_bad_msg_fragments);
80#undef ADD_COMM_TALLIES
81}
82
83
84/* Called only as a tasklet (software IRQ) */
85static void prism2_info_commtallies(local_info_t *local, unsigned char *buf,
86 int left)
87{
88 if (local->tallies32)
89 prism2_info_commtallies32(local, buf, left);
90 else
91 prism2_info_commtallies16(local, buf, left);
92}
93
94
95#ifndef PRISM2_NO_STATION_MODES
96#ifndef PRISM2_NO_DEBUG
97static const char* hfa384x_linkstatus_str(u16 linkstatus)
98{
99 switch (linkstatus) {
100 case HFA384X_LINKSTATUS_CONNECTED:
101 return "Connected";
102 case HFA384X_LINKSTATUS_DISCONNECTED:
103 return "Disconnected";
104 case HFA384X_LINKSTATUS_AP_CHANGE:
105 return "Access point change";
106 case HFA384X_LINKSTATUS_AP_OUT_OF_RANGE:
107 return "Access point out of range";
108 case HFA384X_LINKSTATUS_AP_IN_RANGE:
109 return "Access point in range";
110 case HFA384X_LINKSTATUS_ASSOC_FAILED:
111 return "Association failed";
112 default:
113 return "Unknown";
114 }
115}
116#endif /* PRISM2_NO_DEBUG */
117
118
119/* Called only as a tasklet (software IRQ) */
120static void prism2_info_linkstatus(local_info_t *local, unsigned char *buf,
121 int left)
122{
123 u16 val;
124 int non_sta_mode;
125
126 /* Alloc new JoinRequests to occur since LinkStatus for the previous
127 * has been received */
128 local->last_join_time = 0;
129
130 if (left != 2) {
131 printk(KERN_DEBUG "%s: invalid linkstatus info frame "
132 "length %d\n", local->dev->name, left);
133 return;
134 }
135
136 non_sta_mode = local->iw_mode == IW_MODE_MASTER ||
137 local->iw_mode == IW_MODE_REPEAT ||
138 local->iw_mode == IW_MODE_MONITOR;
139
140 val = buf[0] | (buf[1] << 8);
141 if (!non_sta_mode || val != HFA384X_LINKSTATUS_DISCONNECTED) {
142 PDEBUG(DEBUG_EXTRA, "%s: LinkStatus=%d (%s)\n",
143 local->dev->name, val, hfa384x_linkstatus_str(val));
144 }
145
146 if (non_sta_mode) {
147 netif_carrier_on(local->dev);
148 netif_carrier_on(local->ddev);
149 return;
150 }
151
152 /* Get current BSSID later in scheduled task */
153 set_bit(PRISM2_INFO_PENDING_LINKSTATUS, &local->pending_info);
154 local->prev_link_status = val;
155 schedule_work(&local->info_queue);
156}
157
158
159static void prism2_host_roaming(local_info_t *local)
160{
161 struct hfa384x_join_request req;
162 struct net_device *dev = local->dev;
163 struct hfa384x_hostscan_result *selected, *entry;
164 int i;
165 unsigned long flags;
166
167 if (local->last_join_time &&
168 time_before(jiffies, local->last_join_time + 10 * HZ)) {
169 PDEBUG(DEBUG_EXTRA, "%s: last join request has not yet been "
170 "completed - waiting for it before issuing new one\n",
171 dev->name);
172 return;
173 }
174
175 /* ScanResults are sorted: first ESS results in decreasing signal
176 * quality then IBSS results in similar order.
177 * Trivial roaming policy: just select the first entry.
178 * This could probably be improved by adding hysteresis to limit
179 * number of handoffs, etc.
180 *
181 * Could do periodic RID_SCANREQUEST or Inquire F101 to get new
182 * ScanResults */
183 spin_lock_irqsave(&local->lock, flags);
184 if (local->last_scan_results == NULL ||
185 local->last_scan_results_count == 0) {
186 spin_unlock_irqrestore(&local->lock, flags);
187 PDEBUG(DEBUG_EXTRA, "%s: no scan results for host roaming\n",
188 dev->name);
189 return;
190 }
191
192 selected = &local->last_scan_results[0];
193
194 if (local->preferred_ap[0] || local->preferred_ap[1] ||
195 local->preferred_ap[2] || local->preferred_ap[3] ||
196 local->preferred_ap[4] || local->preferred_ap[5]) {
197 /* Try to find preferred AP */
198 PDEBUG(DEBUG_EXTRA, "%s: Preferred AP BSSID " MACSTR "\n",
199 dev->name, MAC2STR(local->preferred_ap));
200 for (i = 0; i < local->last_scan_results_count; i++) {
201 entry = &local->last_scan_results[i];
202 if (memcmp(local->preferred_ap, entry->bssid, 6) == 0)
203 {
204 PDEBUG(DEBUG_EXTRA, "%s: using preferred AP "
205 "selection\n", dev->name);
206 selected = entry;
207 break;
208 }
209 }
210 }
211
212 memcpy(req.bssid, selected->bssid, 6);
213 req.channel = selected->chid;
214 spin_unlock_irqrestore(&local->lock, flags);
215
216 PDEBUG(DEBUG_EXTRA, "%s: JoinRequest: BSSID=" MACSTR " channel=%d\n",
217 dev->name, MAC2STR(req.bssid), le16_to_cpu(req.channel));
218 if (local->func->set_rid(dev, HFA384X_RID_JOINREQUEST, &req,
219 sizeof(req))) {
220 printk(KERN_DEBUG "%s: JoinRequest failed\n", dev->name);
221 }
222 local->last_join_time = jiffies;
223}
224
225
226static void hostap_report_scan_complete(local_info_t *local)
227{
228 union iwreq_data wrqu;
229
230 /* Inform user space about new scan results (just empty event,
231 * SIOCGIWSCAN can be used to fetch data */
232 wrqu.data.length = 0;
233 wrqu.data.flags = 0;
234 wireless_send_event(local->dev, SIOCGIWSCAN, &wrqu, NULL);
235
236 /* Allow SIOCGIWSCAN handling to occur since we have received
237 * scanning result */
238 local->scan_timestamp = 0;
239}
240
241
242/* Called only as a tasklet (software IRQ) */
243static void prism2_info_scanresults(local_info_t *local, unsigned char *buf,
244 int left)
245{
246 u16 *pos;
247 int new_count, i;
248 unsigned long flags;
249 struct hfa384x_scan_result *res;
250 struct hfa384x_hostscan_result *results, *prev;
251
252 if (left < 4) {
253 printk(KERN_DEBUG "%s: invalid scanresult info frame "
254 "length %d\n", local->dev->name, left);
255 return;
256 }
257
258 pos = (u16 *) buf;
259 pos++;
260 pos++;
261 left -= 4;
262
263 new_count = left / sizeof(struct hfa384x_scan_result);
264 results = kmalloc(new_count * sizeof(struct hfa384x_hostscan_result),
265 GFP_ATOMIC);
266 if (results == NULL)
267 return;
268
269 /* Convert to hostscan result format. */
270 res = (struct hfa384x_scan_result *) pos;
271 for (i = 0; i < new_count; i++) {
272 memcpy(&results[i], &res[i],
273 sizeof(struct hfa384x_scan_result));
274 results[i].atim = 0;
275 }
276
277 spin_lock_irqsave(&local->lock, flags);
278 local->last_scan_type = PRISM2_SCAN;
279 prev = local->last_scan_results;
280 local->last_scan_results = results;
281 local->last_scan_results_count = new_count;
282 spin_unlock_irqrestore(&local->lock, flags);
283 kfree(prev);
284
285 hostap_report_scan_complete(local);
286
287 /* Perform rest of ScanResults handling later in scheduled task */
288 set_bit(PRISM2_INFO_PENDING_SCANRESULTS, &local->pending_info);
289 schedule_work(&local->info_queue);
290}
291
292
293/* Called only as a tasklet (software IRQ) */
294static void prism2_info_hostscanresults(local_info_t *local,
295 unsigned char *buf, int left)
296{
297 int i, result_size, copy_len, new_count;
298 struct hfa384x_hostscan_result *results, *prev;
299 unsigned long flags;
300 u16 *pos;
301 u8 *ptr;
302
303 wake_up_interruptible(&local->hostscan_wq);
304
305 if (left < 4) {
306 printk(KERN_DEBUG "%s: invalid hostscanresult info frame "
307 "length %d\n", local->dev->name, left);
308 return;
309 }
310
311 pos = (u16 *) buf;
312 copy_len = result_size = le16_to_cpu(*pos);
313 if (result_size == 0) {
314 printk(KERN_DEBUG "%s: invalid result_size (0) in "
315 "hostscanresults\n", local->dev->name);
316 return;
317 }
318 if (copy_len > sizeof(struct hfa384x_hostscan_result))
319 copy_len = sizeof(struct hfa384x_hostscan_result);
320
321 pos++;
322 pos++;
323 left -= 4;
324 ptr = (u8 *) pos;
325
326 new_count = left / result_size;
327 results = kmalloc(new_count * sizeof(struct hfa384x_hostscan_result),
328 GFP_ATOMIC);
329 if (results == NULL)
330 return;
331 memset(results, 0, new_count * sizeof(struct hfa384x_hostscan_result));
332
333 for (i = 0; i < new_count; i++) {
334 memcpy(&results[i], ptr, copy_len);
335 ptr += result_size;
336 left -= result_size;
337 }
338
339 if (left) {
340 printk(KERN_DEBUG "%s: short HostScan result entry (%d/%d)\n",
341 local->dev->name, left, result_size);
342 }
343
344 spin_lock_irqsave(&local->lock, flags);
345 local->last_scan_type = PRISM2_HOSTSCAN;
346 prev = local->last_scan_results;
347 local->last_scan_results = results;
348 local->last_scan_results_count = new_count;
349 spin_unlock_irqrestore(&local->lock, flags);
350 kfree(prev);
351
352 hostap_report_scan_complete(local);
353}
354#endif /* PRISM2_NO_STATION_MODES */
355
356
357/* Called only as a tasklet (software IRQ) */
358void hostap_info_process(local_info_t *local, struct sk_buff *skb)
359{
360 struct hfa384x_info_frame *info;
361 unsigned char *buf;
362 int left;
363#ifndef PRISM2_NO_DEBUG
364 int i;
365#endif /* PRISM2_NO_DEBUG */
366
367 info = (struct hfa384x_info_frame *) skb->data;
368 buf = skb->data + sizeof(*info);
369 left = skb->len - sizeof(*info);
370
371 switch (info->type) {
372 case HFA384X_INFO_COMMTALLIES:
373 prism2_info_commtallies(local, buf, left);
374 break;
375
376#ifndef PRISM2_NO_STATION_MODES
377 case HFA384X_INFO_LINKSTATUS:
378 prism2_info_linkstatus(local, buf, left);
379 break;
380
381 case HFA384X_INFO_SCANRESULTS:
382 prism2_info_scanresults(local, buf, left);
383 break;
384
385 case HFA384X_INFO_HOSTSCANRESULTS:
386 prism2_info_hostscanresults(local, buf, left);
387 break;
388#endif /* PRISM2_NO_STATION_MODES */
389
390#ifndef PRISM2_NO_DEBUG
391 default:
392 PDEBUG(DEBUG_EXTRA, "%s: INFO - len=%d type=0x%04x\n",
393 local->dev->name, info->len, info->type);
394 PDEBUG(DEBUG_EXTRA, "Unknown info frame:");
395 for (i = 0; i < (left < 100 ? left : 100); i++)
396 PDEBUG2(DEBUG_EXTRA, " %02x", buf[i]);
397 PDEBUG2(DEBUG_EXTRA, "\n");
398 break;
399#endif /* PRISM2_NO_DEBUG */
400 }
401}
402
403
404#ifndef PRISM2_NO_STATION_MODES
405static void handle_info_queue_linkstatus(local_info_t *local)
406{
407 int val = local->prev_link_status;
408 int connected;
409 union iwreq_data wrqu;
410
411 connected =
412 val == HFA384X_LINKSTATUS_CONNECTED ||
413 val == HFA384X_LINKSTATUS_AP_CHANGE ||
414 val == HFA384X_LINKSTATUS_AP_IN_RANGE;
415
416 if (local->func->get_rid(local->dev, HFA384X_RID_CURRENTBSSID,
417 local->bssid, ETH_ALEN, 1) < 0) {
418 printk(KERN_DEBUG "%s: could not read CURRENTBSSID after "
419 "LinkStatus event\n", local->dev->name);
420 } else {
421 PDEBUG(DEBUG_EXTRA, "%s: LinkStatus: BSSID=" MACSTR "\n",
422 local->dev->name,
423 MAC2STR((unsigned char *) local->bssid));
424 if (local->wds_type & HOSTAP_WDS_AP_CLIENT)
425 hostap_add_sta(local->ap, local->bssid);
426 }
427
428 /* Get BSSID if we have a valid AP address */
429 if (connected) {
430 netif_carrier_on(local->dev);
431 netif_carrier_on(local->ddev);
432 memcpy(wrqu.ap_addr.sa_data, local->bssid, ETH_ALEN);
433 } else {
434 netif_carrier_off(local->dev);
435 netif_carrier_off(local->ddev);
436 memset(wrqu.ap_addr.sa_data, 0, ETH_ALEN);
437 }
438 wrqu.ap_addr.sa_family = ARPHRD_ETHER;
439
440 /*
441 * Filter out sequential disconnect events in order not to cause a
442 * flood of SIOCGIWAP events that have a race condition with EAPOL
443 * frames and can confuse wpa_supplicant about the current association
444 * status.
445 */
446 if (connected || local->prev_linkstatus_connected)
447 wireless_send_event(local->dev, SIOCGIWAP, &wrqu, NULL);
448 local->prev_linkstatus_connected = connected;
449}
450
451
452static void handle_info_queue_scanresults(local_info_t *local)
453{
454 if (local->host_roaming == 1 && local->iw_mode == IW_MODE_INFRA)
455 prism2_host_roaming(local);
456
457 if (local->host_roaming == 2 && local->iw_mode == IW_MODE_INFRA &&
458 memcmp(local->preferred_ap, "\x00\x00\x00\x00\x00\x00",
459 ETH_ALEN) != 0) {
460 /*
461 * Firmware seems to be getting into odd state in host_roaming
462 * mode 2 when hostscan is used without join command, so try
463 * to fix this by re-joining the current AP. This does not
464 * actually trigger a new association if the current AP is
465 * still in the scan results.
466 */
467 prism2_host_roaming(local);
468 }
469}
470
471
472/* Called only as scheduled task after receiving info frames (used to avoid
473 * pending too much time in HW IRQ handler). */
474static void handle_info_queue(void *data)
475{
476 local_info_t *local = (local_info_t *) data;
477
478 if (test_and_clear_bit(PRISM2_INFO_PENDING_LINKSTATUS,
479 &local->pending_info))
480 handle_info_queue_linkstatus(local);
481
482 if (test_and_clear_bit(PRISM2_INFO_PENDING_SCANRESULTS,
483 &local->pending_info))
484 handle_info_queue_scanresults(local);
485}
486#endif /* PRISM2_NO_STATION_MODES */
487
488
489void hostap_info_init(local_info_t *local)
490{
491 skb_queue_head_init(&local->info_list);
492#ifndef PRISM2_NO_STATION_MODES
493 INIT_WORK(&local->info_queue, handle_info_queue, local);
494#endif /* PRISM2_NO_STATION_MODES */
495}
496
497
498EXPORT_SYMBOL(hostap_info_init);
499EXPORT_SYMBOL(hostap_info_process);
diff --git a/drivers/net/wireless/hostap/hostap_ioctl.c b/drivers/net/wireless/hostap/hostap_ioctl.c
new file mode 100644
index 000000000000..e720369a3515
--- /dev/null
+++ b/drivers/net/wireless/hostap/hostap_ioctl.c
@@ -0,0 +1,4102 @@
1/* ioctl() (mostly Linux Wireless Extensions) routines for Host AP driver */
2
3#ifdef in_atomic
4/* Get kernel_locked() for in_atomic() */
5#include <linux/smp_lock.h>
6#endif
7#include <linux/ethtool.h>
8
9
10static struct iw_statistics *hostap_get_wireless_stats(struct net_device *dev)
11{
12 struct hostap_interface *iface;
13 local_info_t *local;
14 struct iw_statistics *wstats;
15
16 iface = netdev_priv(dev);
17 local = iface->local;
18
19 /* Why are we doing that ? Jean II */
20 if (iface->type != HOSTAP_INTERFACE_MAIN)
21 return NULL;
22
23 wstats = &local->wstats;
24
25 wstats->status = 0;
26 wstats->discard.code =
27 local->comm_tallies.rx_discards_wep_undecryptable;
28 wstats->discard.misc =
29 local->comm_tallies.rx_fcs_errors +
30 local->comm_tallies.rx_discards_no_buffer +
31 local->comm_tallies.tx_discards_wrong_sa;
32
33 wstats->discard.retries =
34 local->comm_tallies.tx_retry_limit_exceeded;
35 wstats->discard.fragment =
36 local->comm_tallies.rx_message_in_bad_msg_fragments;
37
38 if (local->iw_mode != IW_MODE_MASTER &&
39 local->iw_mode != IW_MODE_REPEAT) {
40 int update = 1;
41#ifdef in_atomic
42 /* RID reading might sleep and it must not be called in
43 * interrupt context or while atomic. However, this
44 * function seems to be called while atomic (at least in Linux
45 * 2.5.59). Update signal quality values only if in suitable
46 * context. Otherwise, previous values read from tick timer
47 * will be used. */
48 if (in_atomic())
49 update = 0;
50#endif /* in_atomic */
51
52 if (update && prism2_update_comms_qual(dev) == 0)
53 wstats->qual.updated = 7;
54
55 wstats->qual.qual = local->comms_qual;
56 wstats->qual.level = local->avg_signal;
57 wstats->qual.noise = local->avg_noise;
58 } else {
59 wstats->qual.qual = 0;
60 wstats->qual.level = 0;
61 wstats->qual.noise = 0;
62 wstats->qual.updated = 0;
63 }
64
65 return wstats;
66}
67
68
69static int prism2_get_datarates(struct net_device *dev, u8 *rates)
70{
71 struct hostap_interface *iface;
72 local_info_t *local;
73 u8 buf[12];
74 int len;
75 u16 val;
76
77 iface = netdev_priv(dev);
78 local = iface->local;
79
80 len = local->func->get_rid(dev, HFA384X_RID_SUPPORTEDDATARATES, buf,
81 sizeof(buf), 0);
82 if (len < 2)
83 return 0;
84
85 val = le16_to_cpu(*(u16 *) buf); /* string length */
86
87 if (len - 2 < val || val > 10)
88 return 0;
89
90 memcpy(rates, buf + 2, val);
91 return val;
92}
93
94
95static int prism2_get_name(struct net_device *dev,
96 struct iw_request_info *info,
97 char *name, char *extra)
98{
99 u8 rates[10];
100 int len, i, over2 = 0;
101
102 len = prism2_get_datarates(dev, rates);
103
104 for (i = 0; i < len; i++) {
105 if (rates[i] == 0x0b || rates[i] == 0x16) {
106 over2 = 1;
107 break;
108 }
109 }
110
111 strcpy(name, over2 ? "IEEE 802.11b" : "IEEE 802.11-DS");
112
113 return 0;
114}
115
116
117static void prism2_crypt_delayed_deinit(local_info_t *local,
118 struct ieee80211_crypt_data **crypt)
119{
120 struct ieee80211_crypt_data *tmp;
121 unsigned long flags;
122
123 tmp = *crypt;
124 *crypt = NULL;
125
126 if (tmp == NULL)
127 return;
128
129 /* must not run ops->deinit() while there may be pending encrypt or
130 * decrypt operations. Use a list of delayed deinits to avoid needing
131 * locking. */
132
133 spin_lock_irqsave(&local->lock, flags);
134 list_add(&tmp->list, &local->crypt_deinit_list);
135 if (!timer_pending(&local->crypt_deinit_timer)) {
136 local->crypt_deinit_timer.expires = jiffies + HZ;
137 add_timer(&local->crypt_deinit_timer);
138 }
139 spin_unlock_irqrestore(&local->lock, flags);
140}
141
142
143static int prism2_ioctl_siwencode(struct net_device *dev,
144 struct iw_request_info *info,
145 struct iw_point *erq, char *keybuf)
146{
147 struct hostap_interface *iface;
148 local_info_t *local;
149 int i;
150 struct ieee80211_crypt_data **crypt;
151
152 iface = netdev_priv(dev);
153 local = iface->local;
154
155 i = erq->flags & IW_ENCODE_INDEX;
156 if (i < 1 || i > 4)
157 i = local->tx_keyidx;
158 else
159 i--;
160 if (i < 0 || i >= WEP_KEYS)
161 return -EINVAL;
162
163 crypt = &local->crypt[i];
164
165 if (erq->flags & IW_ENCODE_DISABLED) {
166 if (*crypt)
167 prism2_crypt_delayed_deinit(local, crypt);
168 goto done;
169 }
170
171 if (*crypt != NULL && (*crypt)->ops != NULL &&
172 strcmp((*crypt)->ops->name, "WEP") != 0) {
173 /* changing to use WEP; deinit previously used algorithm */
174 prism2_crypt_delayed_deinit(local, crypt);
175 }
176
177 if (*crypt == NULL) {
178 struct ieee80211_crypt_data *new_crypt;
179
180 /* take WEP into use */
181 new_crypt = (struct ieee80211_crypt_data *)
182 kmalloc(sizeof(struct ieee80211_crypt_data),
183 GFP_KERNEL);
184 if (new_crypt == NULL)
185 return -ENOMEM;
186 memset(new_crypt, 0, sizeof(struct ieee80211_crypt_data));
187 new_crypt->ops = ieee80211_get_crypto_ops("WEP");
188 if (!new_crypt->ops) {
189 request_module("ieee80211_crypt_wep");
190 new_crypt->ops = ieee80211_get_crypto_ops("WEP");
191 }
192 if (new_crypt->ops)
193 new_crypt->priv = new_crypt->ops->init(i);
194 if (!new_crypt->ops || !new_crypt->priv) {
195 kfree(new_crypt);
196 new_crypt = NULL;
197
198 printk(KERN_WARNING "%s: could not initialize WEP: "
199 "load module hostap_crypt_wep.o\n",
200 dev->name);
201 return -EOPNOTSUPP;
202 }
203 *crypt = new_crypt;
204 }
205
206 if (erq->length > 0) {
207 int len = erq->length <= 5 ? 5 : 13;
208 int first = 1, j;
209 if (len > erq->length)
210 memset(keybuf + erq->length, 0, len - erq->length);
211 (*crypt)->ops->set_key(keybuf, len, NULL, (*crypt)->priv);
212 for (j = 0; j < WEP_KEYS; j++) {
213 if (j != i && local->crypt[j]) {
214 first = 0;
215 break;
216 }
217 }
218 if (first)
219 local->tx_keyidx = i;
220 } else {
221 /* No key data - just set the default TX key index */
222 local->tx_keyidx = i;
223 }
224
225 done:
226 local->open_wep = erq->flags & IW_ENCODE_OPEN;
227
228 if (hostap_set_encryption(local)) {
229 printk(KERN_DEBUG "%s: set_encryption failed\n", dev->name);
230 return -EINVAL;
231 }
232
233 /* Do not reset port0 if card is in Managed mode since resetting will
234 * generate new IEEE 802.11 authentication which may end up in looping
235 * with IEEE 802.1X. Prism2 documentation seem to require port reset
236 * after WEP configuration. However, keys are apparently changed at
237 * least in Managed mode. */
238 if (local->iw_mode != IW_MODE_INFRA && local->func->reset_port(dev)) {
239 printk(KERN_DEBUG "%s: reset_port failed\n", dev->name);
240 return -EINVAL;
241 }
242
243 return 0;
244}
245
246
247static int prism2_ioctl_giwencode(struct net_device *dev,
248 struct iw_request_info *info,
249 struct iw_point *erq, char *key)
250{
251 struct hostap_interface *iface;
252 local_info_t *local;
253 int i, len;
254 u16 val;
255 struct ieee80211_crypt_data *crypt;
256
257 iface = netdev_priv(dev);
258 local = iface->local;
259
260 i = erq->flags & IW_ENCODE_INDEX;
261 if (i < 1 || i > 4)
262 i = local->tx_keyidx;
263 else
264 i--;
265 if (i < 0 || i >= WEP_KEYS)
266 return -EINVAL;
267
268 crypt = local->crypt[i];
269 erq->flags = i + 1;
270
271 if (crypt == NULL || crypt->ops == NULL) {
272 erq->length = 0;
273 erq->flags |= IW_ENCODE_DISABLED;
274 return 0;
275 }
276
277 if (strcmp(crypt->ops->name, "WEP") != 0) {
278 /* only WEP is supported with wireless extensions, so just
279 * report that encryption is used */
280 erq->length = 0;
281 erq->flags |= IW_ENCODE_ENABLED;
282 return 0;
283 }
284
285 /* Reads from HFA384X_RID_CNFDEFAULTKEY* return bogus values, so show
286 * the keys from driver buffer */
287 len = crypt->ops->get_key(key, WEP_KEY_LEN, NULL, crypt->priv);
288 erq->length = (len >= 0 ? len : 0);
289
290 if (local->func->get_rid(dev, HFA384X_RID_CNFWEPFLAGS, &val, 2, 1) < 0)
291 {
292 printk("CNFWEPFLAGS reading failed\n");
293 return -EOPNOTSUPP;
294 }
295 le16_to_cpus(&val);
296 if (val & HFA384X_WEPFLAGS_PRIVACYINVOKED)
297 erq->flags |= IW_ENCODE_ENABLED;
298 else
299 erq->flags |= IW_ENCODE_DISABLED;
300 if (val & HFA384X_WEPFLAGS_EXCLUDEUNENCRYPTED)
301 erq->flags |= IW_ENCODE_RESTRICTED;
302 else
303 erq->flags |= IW_ENCODE_OPEN;
304
305 return 0;
306}
307
308
309static int hostap_set_rate(struct net_device *dev)
310{
311 struct hostap_interface *iface;
312 local_info_t *local;
313 int ret, basic_rates;
314
315 iface = netdev_priv(dev);
316 local = iface->local;
317
318 basic_rates = local->basic_rates & local->tx_rate_control;
319 if (!basic_rates || basic_rates != local->basic_rates) {
320 printk(KERN_INFO "%s: updating basic rate set automatically "
321 "to match with the new supported rate set\n",
322 dev->name);
323 if (!basic_rates)
324 basic_rates = local->tx_rate_control;
325
326 local->basic_rates = basic_rates;
327 if (hostap_set_word(dev, HFA384X_RID_CNFBASICRATES,
328 basic_rates))
329 printk(KERN_WARNING "%s: failed to set "
330 "cnfBasicRates\n", dev->name);
331 }
332
333 ret = (hostap_set_word(dev, HFA384X_RID_TXRATECONTROL,
334 local->tx_rate_control) ||
335 hostap_set_word(dev, HFA384X_RID_CNFSUPPORTEDRATES,
336 local->tx_rate_control) ||
337 local->func->reset_port(dev));
338
339 if (ret) {
340 printk(KERN_WARNING "%s: TXRateControl/cnfSupportedRates "
341 "setting to 0x%x failed\n",
342 dev->name, local->tx_rate_control);
343 }
344
345 /* Update TX rate configuration for all STAs based on new operational
346 * rate set. */
347 hostap_update_rates(local);
348
349 return ret;
350}
351
352
353static int prism2_ioctl_siwrate(struct net_device *dev,
354 struct iw_request_info *info,
355 struct iw_param *rrq, char *extra)
356{
357 struct hostap_interface *iface;
358 local_info_t *local;
359
360 iface = netdev_priv(dev);
361 local = iface->local;
362
363 if (rrq->fixed) {
364 switch (rrq->value) {
365 case 11000000:
366 local->tx_rate_control = HFA384X_RATES_11MBPS;
367 break;
368 case 5500000:
369 local->tx_rate_control = HFA384X_RATES_5MBPS;
370 break;
371 case 2000000:
372 local->tx_rate_control = HFA384X_RATES_2MBPS;
373 break;
374 case 1000000:
375 local->tx_rate_control = HFA384X_RATES_1MBPS;
376 break;
377 default:
378 local->tx_rate_control = HFA384X_RATES_1MBPS |
379 HFA384X_RATES_2MBPS | HFA384X_RATES_5MBPS |
380 HFA384X_RATES_11MBPS;
381 break;
382 }
383 } else {
384 switch (rrq->value) {
385 case 11000000:
386 local->tx_rate_control = HFA384X_RATES_1MBPS |
387 HFA384X_RATES_2MBPS | HFA384X_RATES_5MBPS |
388 HFA384X_RATES_11MBPS;
389 break;
390 case 5500000:
391 local->tx_rate_control = HFA384X_RATES_1MBPS |
392 HFA384X_RATES_2MBPS | HFA384X_RATES_5MBPS;
393 break;
394 case 2000000:
395 local->tx_rate_control = HFA384X_RATES_1MBPS |
396 HFA384X_RATES_2MBPS;
397 break;
398 case 1000000:
399 local->tx_rate_control = HFA384X_RATES_1MBPS;
400 break;
401 default:
402 local->tx_rate_control = HFA384X_RATES_1MBPS |
403 HFA384X_RATES_2MBPS | HFA384X_RATES_5MBPS |
404 HFA384X_RATES_11MBPS;
405 break;
406 }
407 }
408
409 return hostap_set_rate(dev);
410}
411
412
413static int prism2_ioctl_giwrate(struct net_device *dev,
414 struct iw_request_info *info,
415 struct iw_param *rrq, char *extra)
416{
417 u16 val;
418 struct hostap_interface *iface;
419 local_info_t *local;
420 int ret = 0;
421
422 iface = netdev_priv(dev);
423 local = iface->local;
424
425 if (local->func->get_rid(dev, HFA384X_RID_TXRATECONTROL, &val, 2, 1) <
426 0)
427 return -EINVAL;
428
429 if ((val & 0x1) && (val > 1))
430 rrq->fixed = 0;
431 else
432 rrq->fixed = 1;
433
434 if (local->iw_mode == IW_MODE_MASTER && local->ap != NULL &&
435 !local->fw_tx_rate_control) {
436 /* HFA384X_RID_CURRENTTXRATE seems to always be 2 Mbps in
437 * Host AP mode, so use the recorded TX rate of the last sent
438 * frame */
439 rrq->value = local->ap->last_tx_rate > 0 ?
440 local->ap->last_tx_rate * 100000 : 11000000;
441 return 0;
442 }
443
444 if (local->func->get_rid(dev, HFA384X_RID_CURRENTTXRATE, &val, 2, 1) <
445 0)
446 return -EINVAL;
447
448 switch (val) {
449 case HFA384X_RATES_1MBPS:
450 rrq->value = 1000000;
451 break;
452 case HFA384X_RATES_2MBPS:
453 rrq->value = 2000000;
454 break;
455 case HFA384X_RATES_5MBPS:
456 rrq->value = 5500000;
457 break;
458 case HFA384X_RATES_11MBPS:
459 rrq->value = 11000000;
460 break;
461 default:
462 /* should not happen */
463 rrq->value = 11000000;
464 ret = -EINVAL;
465 break;
466 }
467
468 return ret;
469}
470
471
472static int prism2_ioctl_siwsens(struct net_device *dev,
473 struct iw_request_info *info,
474 struct iw_param *sens, char *extra)
475{
476 struct hostap_interface *iface;
477 local_info_t *local;
478
479 iface = netdev_priv(dev);
480 local = iface->local;
481
482 /* Set the desired AP density */
483 if (sens->value < 1 || sens->value > 3)
484 return -EINVAL;
485
486 if (hostap_set_word(dev, HFA384X_RID_CNFSYSTEMSCALE, sens->value) ||
487 local->func->reset_port(dev))
488 return -EINVAL;
489
490 return 0;
491}
492
493static int prism2_ioctl_giwsens(struct net_device *dev,
494 struct iw_request_info *info,
495 struct iw_param *sens, char *extra)
496{
497 struct hostap_interface *iface;
498 local_info_t *local;
499 u16 val;
500
501 iface = netdev_priv(dev);
502 local = iface->local;
503
504 /* Get the current AP density */
505 if (local->func->get_rid(dev, HFA384X_RID_CNFSYSTEMSCALE, &val, 2, 1) <
506 0)
507 return -EINVAL;
508
509 sens->value = __le16_to_cpu(val);
510 sens->fixed = 1;
511
512 return 0;
513}
514
515
516/* Deprecated in new wireless extension API */
517static int prism2_ioctl_giwaplist(struct net_device *dev,
518 struct iw_request_info *info,
519 struct iw_point *data, char *extra)
520{
521 struct hostap_interface *iface;
522 local_info_t *local;
523 struct sockaddr *addr;
524 struct iw_quality *qual;
525
526 iface = netdev_priv(dev);
527 local = iface->local;
528
529 if (local->iw_mode != IW_MODE_MASTER) {
530 printk(KERN_DEBUG "SIOCGIWAPLIST is currently only supported "
531 "in Host AP mode\n");
532 data->length = 0;
533 return -EOPNOTSUPP;
534 }
535
536 addr = kmalloc(sizeof(struct sockaddr) * IW_MAX_AP, GFP_KERNEL);
537 qual = kmalloc(sizeof(struct iw_quality) * IW_MAX_AP, GFP_KERNEL);
538 if (addr == NULL || qual == NULL) {
539 kfree(addr);
540 kfree(qual);
541 data->length = 0;
542 return -ENOMEM;
543 }
544
545 data->length = prism2_ap_get_sta_qual(local, addr, qual, IW_MAX_AP, 1);
546
547 memcpy(extra, &addr, sizeof(struct sockaddr) * data->length);
548 data->flags = 1; /* has quality information */
549 memcpy(extra + sizeof(struct sockaddr) * data->length, &qual,
550 sizeof(struct iw_quality) * data->length);
551
552 kfree(addr);
553 kfree(qual);
554
555 return 0;
556}
557
558
559static int prism2_ioctl_siwrts(struct net_device *dev,
560 struct iw_request_info *info,
561 struct iw_param *rts, char *extra)
562{
563 struct hostap_interface *iface;
564 local_info_t *local;
565 u16 val;
566
567 iface = netdev_priv(dev);
568 local = iface->local;
569
570 if (rts->disabled)
571 val = __constant_cpu_to_le16(2347);
572 else if (rts->value < 0 || rts->value > 2347)
573 return -EINVAL;
574 else
575 val = __cpu_to_le16(rts->value);
576
577 if (local->func->set_rid(dev, HFA384X_RID_RTSTHRESHOLD, &val, 2) ||
578 local->func->reset_port(dev))
579 return -EINVAL;
580
581 local->rts_threshold = rts->value;
582
583 return 0;
584}
585
586static int prism2_ioctl_giwrts(struct net_device *dev,
587 struct iw_request_info *info,
588 struct iw_param *rts, char *extra)
589{
590 struct hostap_interface *iface;
591 local_info_t *local;
592 u16 val;
593
594 iface = netdev_priv(dev);
595 local = iface->local;
596
597 if (local->func->get_rid(dev, HFA384X_RID_RTSTHRESHOLD, &val, 2, 1) <
598 0)
599 return -EINVAL;
600
601 rts->value = __le16_to_cpu(val);
602 rts->disabled = (rts->value == 2347);
603 rts->fixed = 1;
604
605 return 0;
606}
607
608
609static int prism2_ioctl_siwfrag(struct net_device *dev,
610 struct iw_request_info *info,
611 struct iw_param *rts, char *extra)
612{
613 struct hostap_interface *iface;
614 local_info_t *local;
615 u16 val;
616
617 iface = netdev_priv(dev);
618 local = iface->local;
619
620 if (rts->disabled)
621 val = __constant_cpu_to_le16(2346);
622 else if (rts->value < 256 || rts->value > 2346)
623 return -EINVAL;
624 else
625 val = __cpu_to_le16(rts->value & ~0x1); /* even numbers only */
626
627 local->fragm_threshold = rts->value & ~0x1;
628 if (local->func->set_rid(dev, HFA384X_RID_FRAGMENTATIONTHRESHOLD, &val,
629 2)
630 || local->func->reset_port(dev))
631 return -EINVAL;
632
633 return 0;
634}
635
636static int prism2_ioctl_giwfrag(struct net_device *dev,
637 struct iw_request_info *info,
638 struct iw_param *rts, char *extra)
639{
640 struct hostap_interface *iface;
641 local_info_t *local;
642 u16 val;
643
644 iface = netdev_priv(dev);
645 local = iface->local;
646
647 if (local->func->get_rid(dev, HFA384X_RID_FRAGMENTATIONTHRESHOLD,
648 &val, 2, 1) < 0)
649 return -EINVAL;
650
651 rts->value = __le16_to_cpu(val);
652 rts->disabled = (rts->value == 2346);
653 rts->fixed = 1;
654
655 return 0;
656}
657
658
659#ifndef PRISM2_NO_STATION_MODES
660static int hostap_join_ap(struct net_device *dev)
661{
662 struct hostap_interface *iface;
663 local_info_t *local;
664 struct hfa384x_join_request req;
665 unsigned long flags;
666 int i;
667 struct hfa384x_hostscan_result *entry;
668
669 iface = netdev_priv(dev);
670 local = iface->local;
671
672 memcpy(req.bssid, local->preferred_ap, ETH_ALEN);
673 req.channel = 0;
674
675 spin_lock_irqsave(&local->lock, flags);
676 for (i = 0; i < local->last_scan_results_count; i++) {
677 if (!local->last_scan_results)
678 break;
679 entry = &local->last_scan_results[i];
680 if (memcmp(local->preferred_ap, entry->bssid, ETH_ALEN) == 0) {
681 req.channel = entry->chid;
682 break;
683 }
684 }
685 spin_unlock_irqrestore(&local->lock, flags);
686
687 if (local->func->set_rid(dev, HFA384X_RID_JOINREQUEST, &req,
688 sizeof(req))) {
689 printk(KERN_DEBUG "%s: JoinRequest " MACSTR
690 " failed\n",
691 dev->name, MAC2STR(local->preferred_ap));
692 return -1;
693 }
694
695 printk(KERN_DEBUG "%s: Trying to join BSSID " MACSTR "\n",
696 dev->name, MAC2STR(local->preferred_ap));
697
698 return 0;
699}
700#endif /* PRISM2_NO_STATION_MODES */
701
702
703static int prism2_ioctl_siwap(struct net_device *dev,
704 struct iw_request_info *info,
705 struct sockaddr *ap_addr, char *extra)
706{
707#ifdef PRISM2_NO_STATION_MODES
708 return -EOPNOTSUPP;
709#else /* PRISM2_NO_STATION_MODES */
710 struct hostap_interface *iface;
711 local_info_t *local;
712
713 iface = netdev_priv(dev);
714 local = iface->local;
715
716 memcpy(local->preferred_ap, &ap_addr->sa_data, ETH_ALEN);
717
718 if (local->host_roaming == 1 && local->iw_mode == IW_MODE_INFRA) {
719 struct hfa384x_scan_request scan_req;
720 memset(&scan_req, 0, sizeof(scan_req));
721 scan_req.channel_list = __constant_cpu_to_le16(0x3fff);
722 scan_req.txrate = __constant_cpu_to_le16(HFA384X_RATES_1MBPS);
723 if (local->func->set_rid(dev, HFA384X_RID_SCANREQUEST,
724 &scan_req, sizeof(scan_req))) {
725 printk(KERN_DEBUG "%s: ScanResults request failed - "
726 "preferred AP delayed to next unsolicited "
727 "scan\n", dev->name);
728 }
729 } else if (local->host_roaming == 2 &&
730 local->iw_mode == IW_MODE_INFRA) {
731 if (hostap_join_ap(dev))
732 return -EINVAL;
733 } else {
734 printk(KERN_DEBUG "%s: Preferred AP (SIOCSIWAP) is used only "
735 "in Managed mode when host_roaming is enabled\n",
736 dev->name);
737 }
738
739 return 0;
740#endif /* PRISM2_NO_STATION_MODES */
741}
742
743static int prism2_ioctl_giwap(struct net_device *dev,
744 struct iw_request_info *info,
745 struct sockaddr *ap_addr, char *extra)
746{
747 struct hostap_interface *iface;
748 local_info_t *local;
749
750 iface = netdev_priv(dev);
751 local = iface->local;
752
753 ap_addr->sa_family = ARPHRD_ETHER;
754 switch (iface->type) {
755 case HOSTAP_INTERFACE_AP:
756 memcpy(&ap_addr->sa_data, dev->dev_addr, ETH_ALEN);
757 break;
758 case HOSTAP_INTERFACE_STA:
759 memcpy(&ap_addr->sa_data, local->assoc_ap_addr, ETH_ALEN);
760 break;
761 case HOSTAP_INTERFACE_WDS:
762 memcpy(&ap_addr->sa_data, iface->u.wds.remote_addr, ETH_ALEN);
763 break;
764 default:
765 if (local->func->get_rid(dev, HFA384X_RID_CURRENTBSSID,
766 &ap_addr->sa_data, ETH_ALEN, 1) < 0)
767 return -EOPNOTSUPP;
768
769 /* local->bssid is also updated in LinkStatus handler when in
770 * station mode */
771 memcpy(local->bssid, &ap_addr->sa_data, ETH_ALEN);
772 break;
773 }
774
775 return 0;
776}
777
778
779static int prism2_ioctl_siwnickn(struct net_device *dev,
780 struct iw_request_info *info,
781 struct iw_point *data, char *nickname)
782{
783 struct hostap_interface *iface;
784 local_info_t *local;
785
786 iface = netdev_priv(dev);
787 local = iface->local;
788
789 memset(local->name, 0, sizeof(local->name));
790 memcpy(local->name, nickname, data->length);
791 local->name_set = 1;
792
793 if (hostap_set_string(dev, HFA384X_RID_CNFOWNNAME, local->name) ||
794 local->func->reset_port(dev))
795 return -EINVAL;
796
797 return 0;
798}
799
800static int prism2_ioctl_giwnickn(struct net_device *dev,
801 struct iw_request_info *info,
802 struct iw_point *data, char *nickname)
803{
804 struct hostap_interface *iface;
805 local_info_t *local;
806 int len;
807 char name[MAX_NAME_LEN + 3];
808 u16 val;
809
810 iface = netdev_priv(dev);
811 local = iface->local;
812
813 len = local->func->get_rid(dev, HFA384X_RID_CNFOWNNAME,
814 &name, MAX_NAME_LEN + 2, 0);
815 val = __le16_to_cpu(*(u16 *) name);
816 if (len > MAX_NAME_LEN + 2 || len < 0 || val > MAX_NAME_LEN)
817 return -EOPNOTSUPP;
818
819 name[val + 2] = '\0';
820 data->length = val + 1;
821 memcpy(nickname, name + 2, val + 1);
822
823 return 0;
824}
825
826
827static int prism2_ioctl_siwfreq(struct net_device *dev,
828 struct iw_request_info *info,
829 struct iw_freq *freq, char *extra)
830{
831 struct hostap_interface *iface;
832 local_info_t *local;
833
834 iface = netdev_priv(dev);
835 local = iface->local;
836
837 /* freq => chan. */
838 if (freq->e == 1 &&
839 freq->m / 100000 >= freq_list[0] &&
840 freq->m / 100000 <= freq_list[FREQ_COUNT - 1]) {
841 int ch;
842 int fr = freq->m / 100000;
843 for (ch = 0; ch < FREQ_COUNT; ch++) {
844 if (fr == freq_list[ch]) {
845 freq->e = 0;
846 freq->m = ch + 1;
847 break;
848 }
849 }
850 }
851
852 if (freq->e != 0 || freq->m < 1 || freq->m > FREQ_COUNT ||
853 !(local->channel_mask & (1 << (freq->m - 1))))
854 return -EINVAL;
855
856 local->channel = freq->m; /* channel is used in prism2_setup_rids() */
857 if (hostap_set_word(dev, HFA384X_RID_CNFOWNCHANNEL, local->channel) ||
858 local->func->reset_port(dev))
859 return -EINVAL;
860
861 return 0;
862}
863
864static int prism2_ioctl_giwfreq(struct net_device *dev,
865 struct iw_request_info *info,
866 struct iw_freq *freq, char *extra)
867{
868 struct hostap_interface *iface;
869 local_info_t *local;
870 u16 val;
871
872 iface = netdev_priv(dev);
873 local = iface->local;
874
875 if (local->func->get_rid(dev, HFA384X_RID_CURRENTCHANNEL, &val, 2, 1) <
876 0)
877 return -EINVAL;
878
879 le16_to_cpus(&val);
880 if (val < 1 || val > FREQ_COUNT)
881 return -EINVAL;
882
883 freq->m = freq_list[val - 1] * 100000;
884 freq->e = 1;
885
886 return 0;
887}
888
889
890static void hostap_monitor_set_type(local_info_t *local)
891{
892 struct net_device *dev = local->ddev;
893
894 if (dev == NULL)
895 return;
896
897 if (local->monitor_type == PRISM2_MONITOR_PRISM ||
898 local->monitor_type == PRISM2_MONITOR_CAPHDR) {
899 dev->type = ARPHRD_IEEE80211_PRISM;
900 dev->hard_header_parse =
901 hostap_80211_prism_header_parse;
902 } else {
903 dev->type = ARPHRD_IEEE80211;
904 dev->hard_header_parse = hostap_80211_header_parse;
905 }
906}
907
908
909static int prism2_ioctl_siwessid(struct net_device *dev,
910 struct iw_request_info *info,
911 struct iw_point *data, char *ssid)
912{
913 struct hostap_interface *iface;
914 local_info_t *local;
915
916 iface = netdev_priv(dev);
917 local = iface->local;
918
919 if (iface->type == HOSTAP_INTERFACE_WDS)
920 return -EOPNOTSUPP;
921
922 if (data->flags == 0)
923 ssid[0] = '\0'; /* ANY */
924
925 if (local->iw_mode == IW_MODE_MASTER && ssid[0] == '\0') {
926 /* Setting SSID to empty string seems to kill the card in
927 * Host AP mode */
928 printk(KERN_DEBUG "%s: Host AP mode does not support "
929 "'Any' essid\n", dev->name);
930 return -EINVAL;
931 }
932
933 memcpy(local->essid, ssid, data->length);
934 local->essid[data->length] = '\0';
935
936 if ((!local->fw_ap &&
937 hostap_set_string(dev, HFA384X_RID_CNFDESIREDSSID, local->essid))
938 || hostap_set_string(dev, HFA384X_RID_CNFOWNSSID, local->essid) ||
939 local->func->reset_port(dev))
940 return -EINVAL;
941
942 return 0;
943}
944
945static int prism2_ioctl_giwessid(struct net_device *dev,
946 struct iw_request_info *info,
947 struct iw_point *data, char *essid)
948{
949 struct hostap_interface *iface;
950 local_info_t *local;
951 u16 val;
952
953 iface = netdev_priv(dev);
954 local = iface->local;
955
956 if (iface->type == HOSTAP_INTERFACE_WDS)
957 return -EOPNOTSUPP;
958
959 data->flags = 1; /* active */
960 if (local->iw_mode == IW_MODE_MASTER) {
961 data->length = strlen(local->essid);
962 memcpy(essid, local->essid, IW_ESSID_MAX_SIZE);
963 } else {
964 int len;
965 char ssid[MAX_SSID_LEN + 2];
966 memset(ssid, 0, sizeof(ssid));
967 len = local->func->get_rid(dev, HFA384X_RID_CURRENTSSID,
968 &ssid, MAX_SSID_LEN + 2, 0);
969 val = __le16_to_cpu(*(u16 *) ssid);
970 if (len > MAX_SSID_LEN + 2 || len < 0 || val > MAX_SSID_LEN) {
971 return -EOPNOTSUPP;
972 }
973 data->length = val;
974 memcpy(essid, ssid + 2, IW_ESSID_MAX_SIZE);
975 }
976
977 return 0;
978}
979
980
981static int prism2_ioctl_giwrange(struct net_device *dev,
982 struct iw_request_info *info,
983 struct iw_point *data, char *extra)
984{
985 struct hostap_interface *iface;
986 local_info_t *local;
987 struct iw_range *range = (struct iw_range *) extra;
988 u8 rates[10];
989 u16 val;
990 int i, len, over2;
991
992 iface = netdev_priv(dev);
993 local = iface->local;
994
995 data->length = sizeof(struct iw_range);
996 memset(range, 0, sizeof(struct iw_range));
997
998 /* TODO: could fill num_txpower and txpower array with
999 * something; however, there are 128 different values.. */
1000
1001 range->txpower_capa = IW_TXPOW_DBM;
1002
1003 if (local->iw_mode == IW_MODE_INFRA || local->iw_mode == IW_MODE_ADHOC)
1004 {
1005 range->min_pmp = 1 * 1024;
1006 range->max_pmp = 65535 * 1024;
1007 range->min_pmt = 1 * 1024;
1008 range->max_pmt = 1000 * 1024;
1009 range->pmp_flags = IW_POWER_PERIOD;
1010 range->pmt_flags = IW_POWER_TIMEOUT;
1011 range->pm_capa = IW_POWER_PERIOD | IW_POWER_TIMEOUT |
1012 IW_POWER_UNICAST_R | IW_POWER_ALL_R;
1013 }
1014
1015 range->we_version_compiled = WIRELESS_EXT;
1016 range->we_version_source = 18;
1017
1018 range->retry_capa = IW_RETRY_LIMIT;
1019 range->retry_flags = IW_RETRY_LIMIT;
1020 range->min_retry = 0;
1021 range->max_retry = 255;
1022
1023 range->num_channels = FREQ_COUNT;
1024
1025 val = 0;
1026 for (i = 0; i < FREQ_COUNT; i++) {
1027 if (local->channel_mask & (1 << i)) {
1028 range->freq[val].i = i + 1;
1029 range->freq[val].m = freq_list[i] * 100000;
1030 range->freq[val].e = 1;
1031 val++;
1032 }
1033 if (val == IW_MAX_FREQUENCIES)
1034 break;
1035 }
1036 range->num_frequency = val;
1037
1038 if (local->sta_fw_ver >= PRISM2_FW_VER(1,3,1)) {
1039 range->max_qual.qual = 70; /* what is correct max? This was not
1040 * documented exactly. At least
1041 * 69 has been observed. */
1042 range->max_qual.level = 0; /* dB */
1043 range->max_qual.noise = 0; /* dB */
1044
1045 /* What would be suitable values for "average/typical" qual? */
1046 range->avg_qual.qual = 20;
1047 range->avg_qual.level = -60;
1048 range->avg_qual.noise = -95;
1049 } else {
1050 range->max_qual.qual = 92; /* 0 .. 92 */
1051 range->max_qual.level = 154; /* 27 .. 154 */
1052 range->max_qual.noise = 154; /* 27 .. 154 */
1053 }
1054 range->sensitivity = 3;
1055
1056 range->max_encoding_tokens = WEP_KEYS;
1057 range->num_encoding_sizes = 2;
1058 range->encoding_size[0] = 5;
1059 range->encoding_size[1] = 13;
1060
1061 over2 = 0;
1062 len = prism2_get_datarates(dev, rates);
1063 range->num_bitrates = 0;
1064 for (i = 0; i < len; i++) {
1065 if (range->num_bitrates < IW_MAX_BITRATES) {
1066 range->bitrate[range->num_bitrates] =
1067 rates[i] * 500000;
1068 range->num_bitrates++;
1069 }
1070 if (rates[i] == 0x0b || rates[i] == 0x16)
1071 over2 = 1;
1072 }
1073 /* estimated maximum TCP throughput values (bps) */
1074 range->throughput = over2 ? 5500000 : 1500000;
1075
1076 range->min_rts = 0;
1077 range->max_rts = 2347;
1078 range->min_frag = 256;
1079 range->max_frag = 2346;
1080
1081 /* Event capability (kernel + driver) */
1082 range->event_capa[0] = (IW_EVENT_CAPA_K_0 |
1083 IW_EVENT_CAPA_MASK(SIOCGIWTHRSPY) |
1084 IW_EVENT_CAPA_MASK(SIOCGIWAP) |
1085 IW_EVENT_CAPA_MASK(SIOCGIWSCAN));
1086 range->event_capa[1] = IW_EVENT_CAPA_K_1;
1087 range->event_capa[4] = (IW_EVENT_CAPA_MASK(IWEVTXDROP) |
1088 IW_EVENT_CAPA_MASK(IWEVCUSTOM) |
1089 IW_EVENT_CAPA_MASK(IWEVREGISTERED) |
1090 IW_EVENT_CAPA_MASK(IWEVEXPIRED));
1091
1092 range->enc_capa = IW_ENC_CAPA_WPA | IW_ENC_CAPA_WPA2 |
1093 IW_ENC_CAPA_CIPHER_TKIP | IW_ENC_CAPA_CIPHER_CCMP;
1094
1095 return 0;
1096}
1097
1098
1099static int hostap_monitor_mode_enable(local_info_t *local)
1100{
1101 struct net_device *dev = local->dev;
1102
1103 printk(KERN_DEBUG "Enabling monitor mode\n");
1104 hostap_monitor_set_type(local);
1105
1106 if (hostap_set_word(dev, HFA384X_RID_CNFPORTTYPE,
1107 HFA384X_PORTTYPE_PSEUDO_IBSS)) {
1108 printk(KERN_DEBUG "Port type setting for monitor mode "
1109 "failed\n");
1110 return -EOPNOTSUPP;
1111 }
1112
1113 /* Host decrypt is needed to get the IV and ICV fields;
1114 * however, monitor mode seems to remove WEP flag from frame
1115 * control field */
1116 if (hostap_set_word(dev, HFA384X_RID_CNFWEPFLAGS,
1117 HFA384X_WEPFLAGS_HOSTENCRYPT |
1118 HFA384X_WEPFLAGS_HOSTDECRYPT)) {
1119 printk(KERN_DEBUG "WEP flags setting failed\n");
1120 return -EOPNOTSUPP;
1121 }
1122
1123 if (local->func->reset_port(dev) ||
1124 local->func->cmd(dev, HFA384X_CMDCODE_TEST |
1125 (HFA384X_TEST_MONITOR << 8),
1126 0, NULL, NULL)) {
1127 printk(KERN_DEBUG "Setting monitor mode failed\n");
1128 return -EOPNOTSUPP;
1129 }
1130
1131 return 0;
1132}
1133
1134
1135static int hostap_monitor_mode_disable(local_info_t *local)
1136{
1137 struct net_device *dev = local->ddev;
1138
1139 if (dev == NULL)
1140 return -1;
1141
1142 printk(KERN_DEBUG "%s: Disabling monitor mode\n", dev->name);
1143 dev->type = ARPHRD_ETHER;
1144 dev->hard_header_parse = local->saved_eth_header_parse;
1145 if (local->func->cmd(dev, HFA384X_CMDCODE_TEST |
1146 (HFA384X_TEST_STOP << 8),
1147 0, NULL, NULL))
1148 return -1;
1149 return hostap_set_encryption(local);
1150}
1151
1152
1153static int prism2_ioctl_siwmode(struct net_device *dev,
1154 struct iw_request_info *info,
1155 __u32 *mode, char *extra)
1156{
1157 struct hostap_interface *iface;
1158 local_info_t *local;
1159 int double_reset = 0;
1160
1161 iface = netdev_priv(dev);
1162 local = iface->local;
1163
1164 if (*mode != IW_MODE_ADHOC && *mode != IW_MODE_INFRA &&
1165 *mode != IW_MODE_MASTER && *mode != IW_MODE_REPEAT &&
1166 *mode != IW_MODE_MONITOR)
1167 return -EOPNOTSUPP;
1168
1169#ifdef PRISM2_NO_STATION_MODES
1170 if (*mode == IW_MODE_ADHOC || *mode == IW_MODE_INFRA)
1171 return -EOPNOTSUPP;
1172#endif /* PRISM2_NO_STATION_MODES */
1173
1174 if (*mode == local->iw_mode)
1175 return 0;
1176
1177 if (*mode == IW_MODE_MASTER && local->essid[0] == '\0') {
1178 printk(KERN_WARNING "%s: empty SSID not allowed in Master "
1179 "mode\n", dev->name);
1180 return -EINVAL;
1181 }
1182
1183 if (local->iw_mode == IW_MODE_MONITOR)
1184 hostap_monitor_mode_disable(local);
1185
1186 if ((local->iw_mode == IW_MODE_ADHOC ||
1187 local->iw_mode == IW_MODE_MONITOR) && *mode == IW_MODE_MASTER) {
1188 /* There seems to be a firmware bug in at least STA f/w v1.5.6
1189 * that leaves beacon frames to use IBSS type when moving from
1190 * IBSS to Host AP mode. Doing double Port0 reset seems to be
1191 * enough to workaround this. */
1192 double_reset = 1;
1193 }
1194
1195 printk(KERN_DEBUG "prism2: %s: operating mode changed "
1196 "%d -> %d\n", dev->name, local->iw_mode, *mode);
1197 local->iw_mode = *mode;
1198
1199 if (local->iw_mode == IW_MODE_MONITOR)
1200 hostap_monitor_mode_enable(local);
1201 else if (local->iw_mode == IW_MODE_MASTER && !local->host_encrypt &&
1202 !local->fw_encrypt_ok) {
1203 printk(KERN_DEBUG "%s: defaulting to host-based encryption as "
1204 "a workaround for firmware bug in Host AP mode WEP\n",
1205 dev->name);
1206 local->host_encrypt = 1;
1207 }
1208
1209 if (hostap_set_word(dev, HFA384X_RID_CNFPORTTYPE,
1210 hostap_get_porttype(local)))
1211 return -EOPNOTSUPP;
1212
1213 if (local->func->reset_port(dev))
1214 return -EINVAL;
1215 if (double_reset && local->func->reset_port(dev))
1216 return -EINVAL;
1217
1218 if (local->iw_mode != IW_MODE_INFRA && local->iw_mode != IW_MODE_ADHOC)
1219 {
1220 /* netif_carrier is used only in client modes for now, so make
1221 * sure carrier is on when moving to non-client modes. */
1222 netif_carrier_on(local->dev);
1223 netif_carrier_on(local->ddev);
1224 }
1225 return 0;
1226}
1227
1228
1229static int prism2_ioctl_giwmode(struct net_device *dev,
1230 struct iw_request_info *info,
1231 __u32 *mode, char *extra)
1232{
1233 struct hostap_interface *iface;
1234 local_info_t *local;
1235
1236 iface = netdev_priv(dev);
1237 local = iface->local;
1238
1239 switch (iface->type) {
1240 case HOSTAP_INTERFACE_STA:
1241 *mode = IW_MODE_INFRA;
1242 break;
1243 case HOSTAP_INTERFACE_WDS:
1244 *mode = IW_MODE_REPEAT;
1245 break;
1246 default:
1247 *mode = local->iw_mode;
1248 break;
1249 }
1250 return 0;
1251}
1252
1253
1254static int prism2_ioctl_siwpower(struct net_device *dev,
1255 struct iw_request_info *info,
1256 struct iw_param *wrq, char *extra)
1257{
1258#ifdef PRISM2_NO_STATION_MODES
1259 return -EOPNOTSUPP;
1260#else /* PRISM2_NO_STATION_MODES */
1261 int ret = 0;
1262
1263 if (wrq->disabled)
1264 return hostap_set_word(dev, HFA384X_RID_CNFPMENABLED, 0);
1265
1266 switch (wrq->flags & IW_POWER_MODE) {
1267 case IW_POWER_UNICAST_R:
1268 ret = hostap_set_word(dev, HFA384X_RID_CNFMULTICASTRECEIVE, 0);
1269 if (ret)
1270 return ret;
1271 ret = hostap_set_word(dev, HFA384X_RID_CNFPMENABLED, 1);
1272 if (ret)
1273 return ret;
1274 break;
1275 case IW_POWER_ALL_R:
1276 ret = hostap_set_word(dev, HFA384X_RID_CNFMULTICASTRECEIVE, 1);
1277 if (ret)
1278 return ret;
1279 ret = hostap_set_word(dev, HFA384X_RID_CNFPMENABLED, 1);
1280 if (ret)
1281 return ret;
1282 break;
1283 case IW_POWER_ON:
1284 break;
1285 default:
1286 return -EINVAL;
1287 }
1288
1289 if (wrq->flags & IW_POWER_TIMEOUT) {
1290 ret = hostap_set_word(dev, HFA384X_RID_CNFPMENABLED, 1);
1291 if (ret)
1292 return ret;
1293 ret = hostap_set_word(dev, HFA384X_RID_CNFPMHOLDOVERDURATION,
1294 wrq->value / 1024);
1295 if (ret)
1296 return ret;
1297 }
1298 if (wrq->flags & IW_POWER_PERIOD) {
1299 ret = hostap_set_word(dev, HFA384X_RID_CNFPMENABLED, 1);
1300 if (ret)
1301 return ret;
1302 ret = hostap_set_word(dev, HFA384X_RID_CNFMAXSLEEPDURATION,
1303 wrq->value / 1024);
1304 if (ret)
1305 return ret;
1306 }
1307
1308 return ret;
1309#endif /* PRISM2_NO_STATION_MODES */
1310}
1311
1312
1313static int prism2_ioctl_giwpower(struct net_device *dev,
1314 struct iw_request_info *info,
1315 struct iw_param *rrq, char *extra)
1316{
1317#ifdef PRISM2_NO_STATION_MODES
1318 return -EOPNOTSUPP;
1319#else /* PRISM2_NO_STATION_MODES */
1320 struct hostap_interface *iface;
1321 local_info_t *local;
1322 u16 enable, mcast;
1323
1324 iface = netdev_priv(dev);
1325 local = iface->local;
1326
1327 if (local->func->get_rid(dev, HFA384X_RID_CNFPMENABLED, &enable, 2, 1)
1328 < 0)
1329 return -EINVAL;
1330
1331 if (!__le16_to_cpu(enable)) {
1332 rrq->disabled = 1;
1333 return 0;
1334 }
1335
1336 rrq->disabled = 0;
1337
1338 if ((rrq->flags & IW_POWER_TYPE) == IW_POWER_TIMEOUT) {
1339 u16 timeout;
1340 if (local->func->get_rid(dev,
1341 HFA384X_RID_CNFPMHOLDOVERDURATION,
1342 &timeout, 2, 1) < 0)
1343 return -EINVAL;
1344
1345 rrq->flags = IW_POWER_TIMEOUT;
1346 rrq->value = __le16_to_cpu(timeout) * 1024;
1347 } else {
1348 u16 period;
1349 if (local->func->get_rid(dev, HFA384X_RID_CNFMAXSLEEPDURATION,
1350 &period, 2, 1) < 0)
1351 return -EINVAL;
1352
1353 rrq->flags = IW_POWER_PERIOD;
1354 rrq->value = __le16_to_cpu(period) * 1024;
1355 }
1356
1357 if (local->func->get_rid(dev, HFA384X_RID_CNFMULTICASTRECEIVE, &mcast,
1358 2, 1) < 0)
1359 return -EINVAL;
1360
1361 if (__le16_to_cpu(mcast))
1362 rrq->flags |= IW_POWER_ALL_R;
1363 else
1364 rrq->flags |= IW_POWER_UNICAST_R;
1365
1366 return 0;
1367#endif /* PRISM2_NO_STATION_MODES */
1368}
1369
1370
1371static int prism2_ioctl_siwretry(struct net_device *dev,
1372 struct iw_request_info *info,
1373 struct iw_param *rrq, char *extra)
1374{
1375 struct hostap_interface *iface;
1376 local_info_t *local;
1377
1378 iface = netdev_priv(dev);
1379 local = iface->local;
1380
1381 if (rrq->disabled)
1382 return -EINVAL;
1383
1384 /* setting retry limits is not supported with the current station
1385 * firmware code; simulate this with alternative retry count for now */
1386 if (rrq->flags == IW_RETRY_LIMIT) {
1387 if (rrq->value < 0) {
1388 /* disable manual retry count setting and use firmware
1389 * defaults */
1390 local->manual_retry_count = -1;
1391 local->tx_control &= ~HFA384X_TX_CTRL_ALT_RTRY;
1392 } else {
1393 if (hostap_set_word(dev, HFA384X_RID_CNFALTRETRYCOUNT,
1394 rrq->value)) {
1395 printk(KERN_DEBUG "%s: Alternate retry count "
1396 "setting to %d failed\n",
1397 dev->name, rrq->value);
1398 return -EOPNOTSUPP;
1399 }
1400
1401 local->manual_retry_count = rrq->value;
1402 local->tx_control |= HFA384X_TX_CTRL_ALT_RTRY;
1403 }
1404 return 0;
1405 }
1406
1407 return -EOPNOTSUPP;
1408
1409#if 0
1410 /* what could be done, if firmware would support this.. */
1411
1412 if (rrq->flags & IW_RETRY_LIMIT) {
1413 if (rrq->flags & IW_RETRY_MAX)
1414 HFA384X_RID_LONGRETRYLIMIT = rrq->value;
1415 else if (rrq->flags & IW_RETRY_MIN)
1416 HFA384X_RID_SHORTRETRYLIMIT = rrq->value;
1417 else {
1418 HFA384X_RID_LONGRETRYLIMIT = rrq->value;
1419 HFA384X_RID_SHORTRETRYLIMIT = rrq->value;
1420 }
1421
1422 }
1423
1424 if (rrq->flags & IW_RETRY_LIFETIME) {
1425 HFA384X_RID_MAXTRANSMITLIFETIME = rrq->value / 1024;
1426 }
1427
1428 return 0;
1429#endif /* 0 */
1430}
1431
1432static int prism2_ioctl_giwretry(struct net_device *dev,
1433 struct iw_request_info *info,
1434 struct iw_param *rrq, char *extra)
1435{
1436 struct hostap_interface *iface;
1437 local_info_t *local;
1438 u16 shortretry, longretry, lifetime, altretry;
1439
1440 iface = netdev_priv(dev);
1441 local = iface->local;
1442
1443 if (local->func->get_rid(dev, HFA384X_RID_SHORTRETRYLIMIT, &shortretry,
1444 2, 1) < 0 ||
1445 local->func->get_rid(dev, HFA384X_RID_LONGRETRYLIMIT, &longretry,
1446 2, 1) < 0 ||
1447 local->func->get_rid(dev, HFA384X_RID_MAXTRANSMITLIFETIME,
1448 &lifetime, 2, 1) < 0)
1449 return -EINVAL;
1450
1451 le16_to_cpus(&shortretry);
1452 le16_to_cpus(&longretry);
1453 le16_to_cpus(&lifetime);
1454
1455 rrq->disabled = 0;
1456
1457 if ((rrq->flags & IW_RETRY_TYPE) == IW_RETRY_LIFETIME) {
1458 rrq->flags = IW_RETRY_LIFETIME;
1459 rrq->value = lifetime * 1024;
1460 } else {
1461 if (local->manual_retry_count >= 0) {
1462 rrq->flags = IW_RETRY_LIMIT;
1463 if (local->func->get_rid(dev,
1464 HFA384X_RID_CNFALTRETRYCOUNT,
1465 &altretry, 2, 1) >= 0)
1466 rrq->value = le16_to_cpu(altretry);
1467 else
1468 rrq->value = local->manual_retry_count;
1469 } else if ((rrq->flags & IW_RETRY_MAX)) {
1470 rrq->flags = IW_RETRY_LIMIT | IW_RETRY_MAX;
1471 rrq->value = longretry;
1472 } else {
1473 rrq->flags = IW_RETRY_LIMIT;
1474 rrq->value = shortretry;
1475 if (shortretry != longretry)
1476 rrq->flags |= IW_RETRY_MIN;
1477 }
1478 }
1479 return 0;
1480}
1481
1482
1483/* Note! This TX power controlling is experimental and should not be used in
1484 * production use. It just sets raw power register and does not use any kind of
1485 * feedback information from the measured TX power (CR58). This is now
1486 * commented out to make sure that it is not used by accident. TX power
1487 * configuration will be enabled again after proper algorithm using feedback
1488 * has been implemented. */
1489
1490#ifdef RAW_TXPOWER_SETTING
1491/* Map HFA386x's CR31 to and from dBm with some sort of ad hoc mapping..
1492 * This version assumes following mapping:
1493 * CR31 is 7-bit value with -64 to +63 range.
1494 * -64 is mapped into +20dBm and +63 into -43dBm.
1495 * This is certainly not an exact mapping for every card, but at least
1496 * increasing dBm value should correspond to increasing TX power.
1497 */
1498
1499static int prism2_txpower_hfa386x_to_dBm(u16 val)
1500{
1501 signed char tmp;
1502
1503 if (val > 255)
1504 val = 255;
1505
1506 tmp = val;
1507 tmp >>= 2;
1508
1509 return -12 - tmp;
1510}
1511
1512static u16 prism2_txpower_dBm_to_hfa386x(int val)
1513{
1514 signed char tmp;
1515
1516 if (val > 20)
1517 return 128;
1518 else if (val < -43)
1519 return 127;
1520
1521 tmp = val;
1522 tmp = -12 - tmp;
1523 tmp <<= 2;
1524
1525 return (unsigned char) tmp;
1526}
1527#endif /* RAW_TXPOWER_SETTING */
1528
1529
1530static int prism2_ioctl_siwtxpow(struct net_device *dev,
1531 struct iw_request_info *info,
1532 struct iw_param *rrq, char *extra)
1533{
1534 struct hostap_interface *iface;
1535 local_info_t *local;
1536#ifdef RAW_TXPOWER_SETTING
1537 char *tmp;
1538#endif
1539 u16 val;
1540 int ret = 0;
1541
1542 iface = netdev_priv(dev);
1543 local = iface->local;
1544
1545 if (rrq->disabled) {
1546 if (local->txpower_type != PRISM2_TXPOWER_OFF) {
1547 val = 0xff; /* use all standby and sleep modes */
1548 ret = local->func->cmd(dev, HFA384X_CMDCODE_WRITEMIF,
1549 HFA386X_CR_A_D_TEST_MODES2,
1550 &val, NULL);
1551 printk(KERN_DEBUG "%s: Turning radio off: %s\n",
1552 dev->name, ret ? "failed" : "OK");
1553 local->txpower_type = PRISM2_TXPOWER_OFF;
1554 }
1555 return (ret ? -EOPNOTSUPP : 0);
1556 }
1557
1558 if (local->txpower_type == PRISM2_TXPOWER_OFF) {
1559 val = 0; /* disable all standby and sleep modes */
1560 ret = local->func->cmd(dev, HFA384X_CMDCODE_WRITEMIF,
1561 HFA386X_CR_A_D_TEST_MODES2, &val, NULL);
1562 printk(KERN_DEBUG "%s: Turning radio on: %s\n",
1563 dev->name, ret ? "failed" : "OK");
1564 local->txpower_type = PRISM2_TXPOWER_UNKNOWN;
1565 }
1566
1567#ifdef RAW_TXPOWER_SETTING
1568 if (!rrq->fixed && local->txpower_type != PRISM2_TXPOWER_AUTO) {
1569 printk(KERN_DEBUG "Setting ALC on\n");
1570 val = HFA384X_TEST_CFG_BIT_ALC;
1571 local->func->cmd(dev, HFA384X_CMDCODE_TEST |
1572 (HFA384X_TEST_CFG_BITS << 8), 1, &val, NULL);
1573 local->txpower_type = PRISM2_TXPOWER_AUTO;
1574 return 0;
1575 }
1576
1577 if (local->txpower_type != PRISM2_TXPOWER_FIXED) {
1578 printk(KERN_DEBUG "Setting ALC off\n");
1579 val = HFA384X_TEST_CFG_BIT_ALC;
1580 local->func->cmd(dev, HFA384X_CMDCODE_TEST |
1581 (HFA384X_TEST_CFG_BITS << 8), 0, &val, NULL);
1582 local->txpower_type = PRISM2_TXPOWER_FIXED;
1583 }
1584
1585 if (rrq->flags == IW_TXPOW_DBM)
1586 tmp = "dBm";
1587 else if (rrq->flags == IW_TXPOW_MWATT)
1588 tmp = "mW";
1589 else
1590 tmp = "UNKNOWN";
1591 printk(KERN_DEBUG "Setting TX power to %d %s\n", rrq->value, tmp);
1592
1593 if (rrq->flags != IW_TXPOW_DBM) {
1594 printk("SIOCSIWTXPOW with mW is not supported; use dBm\n");
1595 return -EOPNOTSUPP;
1596 }
1597
1598 local->txpower = rrq->value;
1599 val = prism2_txpower_dBm_to_hfa386x(local->txpower);
1600 if (local->func->cmd(dev, HFA384X_CMDCODE_WRITEMIF,
1601 HFA386X_CR_MANUAL_TX_POWER, &val, NULL))
1602 ret = -EOPNOTSUPP;
1603#else /* RAW_TXPOWER_SETTING */
1604 if (rrq->fixed)
1605 ret = -EOPNOTSUPP;
1606#endif /* RAW_TXPOWER_SETTING */
1607
1608 return ret;
1609}
1610
1611static int prism2_ioctl_giwtxpow(struct net_device *dev,
1612 struct iw_request_info *info,
1613 struct iw_param *rrq, char *extra)
1614{
1615#ifdef RAW_TXPOWER_SETTING
1616 struct hostap_interface *iface;
1617 local_info_t *local;
1618 u16 resp0;
1619
1620 iface = netdev_priv(dev);
1621 local = iface->local;
1622
1623 rrq->flags = IW_TXPOW_DBM;
1624 rrq->disabled = 0;
1625 rrq->fixed = 0;
1626
1627 if (local->txpower_type == PRISM2_TXPOWER_AUTO) {
1628 if (local->func->cmd(dev, HFA384X_CMDCODE_READMIF,
1629 HFA386X_CR_MANUAL_TX_POWER,
1630 NULL, &resp0) == 0) {
1631 rrq->value = prism2_txpower_hfa386x_to_dBm(resp0);
1632 } else {
1633 /* Could not get real txpower; guess 15 dBm */
1634 rrq->value = 15;
1635 }
1636 } else if (local->txpower_type == PRISM2_TXPOWER_OFF) {
1637 rrq->value = 0;
1638 rrq->disabled = 1;
1639 } else if (local->txpower_type == PRISM2_TXPOWER_FIXED) {
1640 rrq->value = local->txpower;
1641 rrq->fixed = 1;
1642 } else {
1643 printk("SIOCGIWTXPOW - unknown txpower_type=%d\n",
1644 local->txpower_type);
1645 }
1646 return 0;
1647#else /* RAW_TXPOWER_SETTING */
1648 return -EOPNOTSUPP;
1649#endif /* RAW_TXPOWER_SETTING */
1650}
1651
1652
1653#ifndef PRISM2_NO_STATION_MODES
1654
1655/* HostScan request works with and without host_roaming mode. In addition, it
1656 * does not break current association. However, it requires newer station
1657 * firmware version (>= 1.3.1) than scan request. */
1658static int prism2_request_hostscan(struct net_device *dev,
1659 u8 *ssid, u8 ssid_len)
1660{
1661 struct hostap_interface *iface;
1662 local_info_t *local;
1663 struct hfa384x_hostscan_request scan_req;
1664
1665 iface = netdev_priv(dev);
1666 local = iface->local;
1667
1668 memset(&scan_req, 0, sizeof(scan_req));
1669 scan_req.channel_list = cpu_to_le16(local->channel_mask &
1670 local->scan_channel_mask);
1671 scan_req.txrate = __constant_cpu_to_le16(HFA384X_RATES_1MBPS);
1672 if (ssid) {
1673 if (ssid_len > 32)
1674 return -EINVAL;
1675 scan_req.target_ssid_len = cpu_to_le16(ssid_len);
1676 memcpy(scan_req.target_ssid, ssid, ssid_len);
1677 }
1678
1679 if (local->func->set_rid(dev, HFA384X_RID_HOSTSCAN, &scan_req,
1680 sizeof(scan_req))) {
1681 printk(KERN_DEBUG "%s: HOSTSCAN failed\n", dev->name);
1682 return -EINVAL;
1683 }
1684 return 0;
1685}
1686
1687
1688static int prism2_request_scan(struct net_device *dev)
1689{
1690 struct hostap_interface *iface;
1691 local_info_t *local;
1692 struct hfa384x_scan_request scan_req;
1693 int ret = 0;
1694
1695 iface = netdev_priv(dev);
1696 local = iface->local;
1697
1698 memset(&scan_req, 0, sizeof(scan_req));
1699 scan_req.channel_list = cpu_to_le16(local->channel_mask &
1700 local->scan_channel_mask);
1701 scan_req.txrate = __constant_cpu_to_le16(HFA384X_RATES_1MBPS);
1702
1703 /* FIX:
1704 * It seems to be enough to set roaming mode for a short moment to
1705 * host-based and then setup scanrequest data and return the mode to
1706 * firmware-based.
1707 *
1708 * Master mode would need to drop to Managed mode for a short while
1709 * to make scanning work.. Or sweep through the different channels and
1710 * use passive scan based on beacons. */
1711
1712 if (!local->host_roaming)
1713 hostap_set_word(dev, HFA384X_RID_CNFROAMINGMODE,
1714 HFA384X_ROAMING_HOST);
1715
1716 if (local->func->set_rid(dev, HFA384X_RID_SCANREQUEST, &scan_req,
1717 sizeof(scan_req))) {
1718 printk(KERN_DEBUG "SCANREQUEST failed\n");
1719 ret = -EINVAL;
1720 }
1721
1722 if (!local->host_roaming)
1723 hostap_set_word(dev, HFA384X_RID_CNFROAMINGMODE,
1724 HFA384X_ROAMING_FIRMWARE);
1725
1726 return 0;
1727}
1728
1729#else /* !PRISM2_NO_STATION_MODES */
1730
1731static inline int prism2_request_hostscan(struct net_device *dev,
1732 u8 *ssid, u8 ssid_len)
1733{
1734 return -EOPNOTSUPP;
1735}
1736
1737
1738static inline int prism2_request_scan(struct net_device *dev)
1739{
1740 return -EOPNOTSUPP;
1741}
1742
1743#endif /* !PRISM2_NO_STATION_MODES */
1744
1745
1746static int prism2_ioctl_siwscan(struct net_device *dev,
1747 struct iw_request_info *info,
1748 struct iw_point *data, char *extra)
1749{
1750 struct hostap_interface *iface;
1751 local_info_t *local;
1752 int ret;
1753 u8 *ssid = NULL, ssid_len = 0;
1754 struct iw_scan_req *req = (struct iw_scan_req *) extra;
1755
1756 iface = netdev_priv(dev);
1757 local = iface->local;
1758
1759 if (data->length < sizeof(struct iw_scan_req))
1760 req = NULL;
1761
1762 if (local->iw_mode == IW_MODE_MASTER) {
1763 /* In master mode, we just return the results of our local
1764 * tables, so we don't need to start anything...
1765 * Jean II */
1766 data->length = 0;
1767 return 0;
1768 }
1769
1770 if (!local->dev_enabled)
1771 return -ENETDOWN;
1772
1773 if (req && data->flags & IW_SCAN_THIS_ESSID) {
1774 ssid = req->essid;
1775 ssid_len = req->essid_len;
1776
1777 if (ssid_len &&
1778 ((local->iw_mode != IW_MODE_INFRA &&
1779 local->iw_mode != IW_MODE_ADHOC) ||
1780 (local->sta_fw_ver < PRISM2_FW_VER(1,3,1))))
1781 return -EOPNOTSUPP;
1782 }
1783
1784 if (local->sta_fw_ver >= PRISM2_FW_VER(1,3,1))
1785 ret = prism2_request_hostscan(dev, ssid, ssid_len);
1786 else
1787 ret = prism2_request_scan(dev);
1788
1789 if (ret == 0)
1790 local->scan_timestamp = jiffies;
1791
1792 /* Could inquire F101, F103 or wait for SIOCGIWSCAN and read RID */
1793
1794 return ret;
1795}
1796
1797
1798#ifndef PRISM2_NO_STATION_MODES
1799static char * __prism2_translate_scan(local_info_t *local,
1800 struct hfa384x_hostscan_result *scan,
1801 struct hostap_bss_info *bss,
1802 char *current_ev, char *end_buf)
1803{
1804 int i, chan;
1805 struct iw_event iwe;
1806 char *current_val;
1807 u16 capabilities;
1808 u8 *pos;
1809 u8 *ssid, *bssid;
1810 size_t ssid_len;
1811 char *buf;
1812
1813 if (bss) {
1814 ssid = bss->ssid;
1815 ssid_len = bss->ssid_len;
1816 bssid = bss->bssid;
1817 } else {
1818 ssid = scan->ssid;
1819 ssid_len = le16_to_cpu(scan->ssid_len);
1820 bssid = scan->bssid;
1821 }
1822 if (ssid_len > 32)
1823 ssid_len = 32;
1824
1825 /* First entry *MUST* be the AP MAC address */
1826 memset(&iwe, 0, sizeof(iwe));
1827 iwe.cmd = SIOCGIWAP;
1828 iwe.u.ap_addr.sa_family = ARPHRD_ETHER;
1829 memcpy(iwe.u.ap_addr.sa_data, bssid, ETH_ALEN);
1830 /* FIX:
1831 * I do not know how this is possible, but iwe_stream_add_event
1832 * seems to re-order memcpy execution so that len is set only
1833 * after copying.. Pre-setting len here "fixes" this, but real
1834 * problems should be solved (after which these iwe.len
1835 * settings could be removed from this function). */
1836 iwe.len = IW_EV_ADDR_LEN;
1837 current_ev = iwe_stream_add_event(current_ev, end_buf, &iwe,
1838 IW_EV_ADDR_LEN);
1839
1840 /* Other entries will be displayed in the order we give them */
1841
1842 memset(&iwe, 0, sizeof(iwe));
1843 iwe.cmd = SIOCGIWESSID;
1844 iwe.u.data.length = ssid_len;
1845 iwe.u.data.flags = 1;
1846 iwe.len = IW_EV_POINT_LEN + iwe.u.data.length;
1847 current_ev = iwe_stream_add_point(current_ev, end_buf, &iwe, ssid);
1848
1849 memset(&iwe, 0, sizeof(iwe));
1850 iwe.cmd = SIOCGIWMODE;
1851 if (bss) {
1852 capabilities = bss->capab_info;
1853 } else {
1854 capabilities = le16_to_cpu(scan->capability);
1855 }
1856 if (capabilities & (WLAN_CAPABILITY_ESS |
1857 WLAN_CAPABILITY_IBSS)) {
1858 if (capabilities & WLAN_CAPABILITY_ESS)
1859 iwe.u.mode = IW_MODE_MASTER;
1860 else
1861 iwe.u.mode = IW_MODE_ADHOC;
1862 iwe.len = IW_EV_UINT_LEN;
1863 current_ev = iwe_stream_add_event(current_ev, end_buf, &iwe,
1864 IW_EV_UINT_LEN);
1865 }
1866
1867 memset(&iwe, 0, sizeof(iwe));
1868 iwe.cmd = SIOCGIWFREQ;
1869 if (scan) {
1870 chan = scan->chid;
1871 } else if (bss) {
1872 chan = bss->chan;
1873 } else {
1874 chan = 0;
1875 }
1876
1877 if (chan > 0) {
1878 iwe.u.freq.m = freq_list[le16_to_cpu(chan - 1)] * 100000;
1879 iwe.u.freq.e = 1;
1880 iwe.len = IW_EV_FREQ_LEN;
1881 current_ev = iwe_stream_add_event(current_ev, end_buf, &iwe,
1882 IW_EV_FREQ_LEN);
1883 }
1884
1885 if (scan) {
1886 memset(&iwe, 0, sizeof(iwe));
1887 iwe.cmd = IWEVQUAL;
1888 if (local->last_scan_type == PRISM2_HOSTSCAN) {
1889 iwe.u.qual.level = le16_to_cpu(scan->sl);
1890 iwe.u.qual.noise = le16_to_cpu(scan->anl);
1891 } else {
1892 iwe.u.qual.level =
1893 HFA384X_LEVEL_TO_dBm(le16_to_cpu(scan->sl));
1894 iwe.u.qual.noise =
1895 HFA384X_LEVEL_TO_dBm(le16_to_cpu(scan->anl));
1896 }
1897 iwe.len = IW_EV_QUAL_LEN;
1898 current_ev = iwe_stream_add_event(current_ev, end_buf, &iwe,
1899 IW_EV_QUAL_LEN);
1900 }
1901
1902 memset(&iwe, 0, sizeof(iwe));
1903 iwe.cmd = SIOCGIWENCODE;
1904 if (capabilities & WLAN_CAPABILITY_PRIVACY)
1905 iwe.u.data.flags = IW_ENCODE_ENABLED | IW_ENCODE_NOKEY;
1906 else
1907 iwe.u.data.flags = IW_ENCODE_DISABLED;
1908 iwe.u.data.length = 0;
1909 iwe.len = IW_EV_POINT_LEN + iwe.u.data.length;
1910 current_ev = iwe_stream_add_point(current_ev, end_buf, &iwe, "");
1911
1912 /* TODO: add SuppRates into BSS table */
1913 if (scan) {
1914 memset(&iwe, 0, sizeof(iwe));
1915 iwe.cmd = SIOCGIWRATE;
1916 current_val = current_ev + IW_EV_LCP_LEN;
1917 pos = scan->sup_rates;
1918 for (i = 0; i < sizeof(scan->sup_rates); i++) {
1919 if (pos[i] == 0)
1920 break;
1921 /* Bit rate given in 500 kb/s units (+ 0x80) */
1922 iwe.u.bitrate.value = ((pos[i] & 0x7f) * 500000);
1923 current_val = iwe_stream_add_value(
1924 current_ev, current_val, end_buf, &iwe,
1925 IW_EV_PARAM_LEN);
1926 }
1927 /* Check if we added any event */
1928 if ((current_val - current_ev) > IW_EV_LCP_LEN)
1929 current_ev = current_val;
1930 }
1931
1932 /* TODO: add BeaconInt,resp_rate,atim into BSS table */
1933 buf = kmalloc(MAX_WPA_IE_LEN * 2 + 30, GFP_KERNEL);
1934 if (buf && scan) {
1935 memset(&iwe, 0, sizeof(iwe));
1936 iwe.cmd = IWEVCUSTOM;
1937 sprintf(buf, "bcn_int=%d", le16_to_cpu(scan->beacon_interval));
1938 iwe.u.data.length = strlen(buf);
1939 current_ev = iwe_stream_add_point(current_ev, end_buf, &iwe,
1940 buf);
1941
1942 memset(&iwe, 0, sizeof(iwe));
1943 iwe.cmd = IWEVCUSTOM;
1944 sprintf(buf, "resp_rate=%d", le16_to_cpu(scan->rate));
1945 iwe.u.data.length = strlen(buf);
1946 current_ev = iwe_stream_add_point(current_ev, end_buf, &iwe,
1947 buf);
1948
1949 if (local->last_scan_type == PRISM2_HOSTSCAN &&
1950 (capabilities & WLAN_CAPABILITY_IBSS)) {
1951 memset(&iwe, 0, sizeof(iwe));
1952 iwe.cmd = IWEVCUSTOM;
1953 sprintf(buf, "atim=%d", le16_to_cpu(scan->atim));
1954 iwe.u.data.length = strlen(buf);
1955 current_ev = iwe_stream_add_point(current_ev, end_buf,
1956 &iwe, buf);
1957 }
1958 }
1959 kfree(buf);
1960
1961 if (bss && bss->wpa_ie_len > 0 && bss->wpa_ie_len <= MAX_WPA_IE_LEN) {
1962 memset(&iwe, 0, sizeof(iwe));
1963 iwe.cmd = IWEVGENIE;
1964 iwe.u.data.length = bss->wpa_ie_len;
1965 current_ev = iwe_stream_add_point(
1966 current_ev, end_buf, &iwe, bss->wpa_ie);
1967 }
1968
1969 if (bss && bss->rsn_ie_len > 0 && bss->rsn_ie_len <= MAX_WPA_IE_LEN) {
1970 memset(&iwe, 0, sizeof(iwe));
1971 iwe.cmd = IWEVGENIE;
1972 iwe.u.data.length = bss->rsn_ie_len;
1973 current_ev = iwe_stream_add_point(
1974 current_ev, end_buf, &iwe, bss->rsn_ie);
1975 }
1976
1977 return current_ev;
1978}
1979
1980
1981/* Translate scan data returned from the card to a card independant
1982 * format that the Wireless Tools will understand - Jean II */
1983static inline int prism2_translate_scan(local_info_t *local,
1984 char *buffer, int buflen)
1985{
1986 struct hfa384x_hostscan_result *scan;
1987 int entry, hostscan;
1988 char *current_ev = buffer;
1989 char *end_buf = buffer + buflen;
1990 struct list_head *ptr;
1991
1992 spin_lock_bh(&local->lock);
1993
1994 list_for_each(ptr, &local->bss_list) {
1995 struct hostap_bss_info *bss;
1996 bss = list_entry(ptr, struct hostap_bss_info, list);
1997 bss->included = 0;
1998 }
1999
2000 hostscan = local->last_scan_type == PRISM2_HOSTSCAN;
2001 for (entry = 0; entry < local->last_scan_results_count; entry++) {
2002 int found = 0;
2003 scan = &local->last_scan_results[entry];
2004
2005 /* Report every SSID if the AP is using multiple SSIDs. If no
2006 * BSS record is found (e.g., when WPA mode is disabled),
2007 * report the AP once. */
2008 list_for_each(ptr, &local->bss_list) {
2009 struct hostap_bss_info *bss;
2010 bss = list_entry(ptr, struct hostap_bss_info, list);
2011 if (memcmp(bss->bssid, scan->bssid, ETH_ALEN) == 0) {
2012 bss->included = 1;
2013 current_ev = __prism2_translate_scan(
2014 local, scan, bss, current_ev, end_buf);
2015 found++;
2016 }
2017 }
2018 if (!found) {
2019 current_ev = __prism2_translate_scan(
2020 local, scan, NULL, current_ev, end_buf);
2021 }
2022 /* Check if there is space for one more entry */
2023 if ((end_buf - current_ev) <= IW_EV_ADDR_LEN) {
2024 /* Ask user space to try again with a bigger buffer */
2025 spin_unlock_bh(&local->lock);
2026 return -E2BIG;
2027 }
2028 }
2029
2030 /* Prism2 firmware has limits (32 at least in some versions) for number
2031 * of BSSes in scan results. Extend this limit by using local BSS list.
2032 */
2033 list_for_each(ptr, &local->bss_list) {
2034 struct hostap_bss_info *bss;
2035 bss = list_entry(ptr, struct hostap_bss_info, list);
2036 if (bss->included)
2037 continue;
2038 current_ev = __prism2_translate_scan(local, NULL, bss,
2039 current_ev, end_buf);
2040 /* Check if there is space for one more entry */
2041 if ((end_buf - current_ev) <= IW_EV_ADDR_LEN) {
2042 /* Ask user space to try again with a bigger buffer */
2043 spin_unlock_bh(&local->lock);
2044 return -E2BIG;
2045 }
2046 }
2047
2048 spin_unlock_bh(&local->lock);
2049
2050 return current_ev - buffer;
2051}
2052#endif /* PRISM2_NO_STATION_MODES */
2053
2054
2055static inline int prism2_ioctl_giwscan_sta(struct net_device *dev,
2056 struct iw_request_info *info,
2057 struct iw_point *data, char *extra)
2058{
2059#ifdef PRISM2_NO_STATION_MODES
2060 return -EOPNOTSUPP;
2061#else /* PRISM2_NO_STATION_MODES */
2062 struct hostap_interface *iface;
2063 local_info_t *local;
2064 int res;
2065
2066 iface = netdev_priv(dev);
2067 local = iface->local;
2068
2069 /* Wait until the scan is finished. We can probably do better
2070 * than that - Jean II */
2071 if (local->scan_timestamp &&
2072 time_before(jiffies, local->scan_timestamp + 3 * HZ)) {
2073 /* Important note : we don't want to block the caller
2074 * until results are ready for various reasons.
2075 * First, managing wait queues is complex and racy
2076 * (there may be multiple simultaneous callers).
2077 * Second, we grab some rtnetlink lock before comming
2078 * here (in dev_ioctl()).
2079 * Third, the caller can wait on the Wireless Event
2080 * - Jean II */
2081 return -EAGAIN;
2082 }
2083 local->scan_timestamp = 0;
2084
2085 res = prism2_translate_scan(local, extra, data->length);
2086
2087 if (res >= 0) {
2088 data->length = res;
2089 return 0;
2090 } else {
2091 data->length = 0;
2092 return res;
2093 }
2094#endif /* PRISM2_NO_STATION_MODES */
2095}
2096
2097
2098static int prism2_ioctl_giwscan(struct net_device *dev,
2099 struct iw_request_info *info,
2100 struct iw_point *data, char *extra)
2101{
2102 struct hostap_interface *iface;
2103 local_info_t *local;
2104 int res;
2105
2106 iface = netdev_priv(dev);
2107 local = iface->local;
2108
2109 if (local->iw_mode == IW_MODE_MASTER) {
2110 /* In MASTER mode, it doesn't make sense to go around
2111 * scanning the frequencies and make the stations we serve
2112 * wait when what the user is really interested about is the
2113 * list of stations and access points we are talking to.
2114 * So, just extract results from our cache...
2115 * Jean II */
2116
2117 /* Translate to WE format */
2118 res = prism2_ap_translate_scan(dev, extra);
2119 if (res >= 0) {
2120 printk(KERN_DEBUG "Scan result translation succeeded "
2121 "(length=%d)\n", res);
2122 data->length = res;
2123 return 0;
2124 } else {
2125 printk(KERN_DEBUG
2126 "Scan result translation failed (res=%d)\n",
2127 res);
2128 data->length = 0;
2129 return res;
2130 }
2131 } else {
2132 /* Station mode */
2133 return prism2_ioctl_giwscan_sta(dev, info, data, extra);
2134 }
2135}
2136
2137
2138static const struct iw_priv_args prism2_priv[] = {
2139 { PRISM2_IOCTL_MONITOR,
2140 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "monitor" },
2141 { PRISM2_IOCTL_READMIF,
2142 IW_PRIV_TYPE_BYTE | IW_PRIV_SIZE_FIXED | 1,
2143 IW_PRIV_TYPE_BYTE | IW_PRIV_SIZE_FIXED | 1, "readmif" },
2144 { PRISM2_IOCTL_WRITEMIF,
2145 IW_PRIV_TYPE_BYTE | IW_PRIV_SIZE_FIXED | 2, 0, "writemif" },
2146 { PRISM2_IOCTL_RESET,
2147 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "reset" },
2148 { PRISM2_IOCTL_INQUIRE,
2149 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "inquire" },
2150 { PRISM2_IOCTL_SET_RID_WORD,
2151 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 2, 0, "set_rid_word" },
2152 { PRISM2_IOCTL_MACCMD,
2153 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "maccmd" },
2154 { PRISM2_IOCTL_WDS_ADD,
2155 IW_PRIV_TYPE_ADDR | IW_PRIV_SIZE_FIXED | 1, 0, "wds_add" },
2156 { PRISM2_IOCTL_WDS_DEL,
2157 IW_PRIV_TYPE_ADDR | IW_PRIV_SIZE_FIXED | 1, 0, "wds_del" },
2158 { PRISM2_IOCTL_ADDMAC,
2159 IW_PRIV_TYPE_ADDR | IW_PRIV_SIZE_FIXED | 1, 0, "addmac" },
2160 { PRISM2_IOCTL_DELMAC,
2161 IW_PRIV_TYPE_ADDR | IW_PRIV_SIZE_FIXED | 1, 0, "delmac" },
2162 { PRISM2_IOCTL_KICKMAC,
2163 IW_PRIV_TYPE_ADDR | IW_PRIV_SIZE_FIXED | 1, 0, "kickmac" },
2164 /* --- raw access to sub-ioctls --- */
2165 { PRISM2_IOCTL_PRISM2_PARAM,
2166 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 2, 0, "prism2_param" },
2167 { PRISM2_IOCTL_GET_PRISM2_PARAM,
2168 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
2169 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, "getprism2_param" },
2170 /* --- sub-ioctls handlers --- */
2171 { PRISM2_IOCTL_PRISM2_PARAM,
2172 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "" },
2173 { PRISM2_IOCTL_GET_PRISM2_PARAM,
2174 0, IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, "" },
2175 /* --- sub-ioctls definitions --- */
2176 { PRISM2_PARAM_TXRATECTRL,
2177 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "txratectrl" },
2178 { PRISM2_PARAM_TXRATECTRL,
2179 0, IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, "gettxratectrl" },
2180 { PRISM2_PARAM_BEACON_INT,
2181 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "beacon_int" },
2182 { PRISM2_PARAM_BEACON_INT,
2183 0, IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, "getbeacon_int" },
2184#ifndef PRISM2_NO_STATION_MODES
2185 { PRISM2_PARAM_PSEUDO_IBSS,
2186 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "pseudo_ibss" },
2187 { PRISM2_PARAM_PSEUDO_IBSS,
2188 0, IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, "getpseudo_ibss" },
2189#endif /* PRISM2_NO_STATION_MODES */
2190 { PRISM2_PARAM_ALC,
2191 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "alc" },
2192 { PRISM2_PARAM_ALC,
2193 0, IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, "getalc" },
2194 { PRISM2_PARAM_DUMP,
2195 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "dump" },
2196 { PRISM2_PARAM_DUMP,
2197 0, IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, "getdump" },
2198 { PRISM2_PARAM_OTHER_AP_POLICY,
2199 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "other_ap_policy" },
2200 { PRISM2_PARAM_OTHER_AP_POLICY,
2201 0, IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, "getother_ap_pol" },
2202 { PRISM2_PARAM_AP_MAX_INACTIVITY,
2203 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "max_inactivity" },
2204 { PRISM2_PARAM_AP_MAX_INACTIVITY,
2205 0, IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, "getmax_inactivi" },
2206 { PRISM2_PARAM_AP_BRIDGE_PACKETS,
2207 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "bridge_packets" },
2208 { PRISM2_PARAM_AP_BRIDGE_PACKETS,
2209 0, IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, "getbridge_packe" },
2210 { PRISM2_PARAM_DTIM_PERIOD,
2211 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "dtim_period" },
2212 { PRISM2_PARAM_DTIM_PERIOD,
2213 0, IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, "getdtim_period" },
2214 { PRISM2_PARAM_AP_NULLFUNC_ACK,
2215 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "nullfunc_ack" },
2216 { PRISM2_PARAM_AP_NULLFUNC_ACK,
2217 0, IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, "getnullfunc_ack" },
2218 { PRISM2_PARAM_MAX_WDS,
2219 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "max_wds" },
2220 { PRISM2_PARAM_MAX_WDS,
2221 0, IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, "getmax_wds" },
2222 { PRISM2_PARAM_AP_AUTOM_AP_WDS,
2223 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "autom_ap_wds" },
2224 { PRISM2_PARAM_AP_AUTOM_AP_WDS,
2225 0, IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, "getautom_ap_wds" },
2226 { PRISM2_PARAM_AP_AUTH_ALGS,
2227 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "ap_auth_algs" },
2228 { PRISM2_PARAM_AP_AUTH_ALGS,
2229 0, IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, "getap_auth_algs" },
2230 { PRISM2_PARAM_MONITOR_ALLOW_FCSERR,
2231 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "allow_fcserr" },
2232 { PRISM2_PARAM_MONITOR_ALLOW_FCSERR,
2233 0, IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, "getallow_fcserr" },
2234 { PRISM2_PARAM_HOST_ENCRYPT,
2235 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "host_encrypt" },
2236 { PRISM2_PARAM_HOST_ENCRYPT,
2237 0, IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, "gethost_encrypt" },
2238 { PRISM2_PARAM_HOST_DECRYPT,
2239 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "host_decrypt" },
2240 { PRISM2_PARAM_HOST_DECRYPT,
2241 0, IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, "gethost_decrypt" },
2242#ifndef PRISM2_NO_STATION_MODES
2243 { PRISM2_PARAM_HOST_ROAMING,
2244 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "host_roaming" },
2245 { PRISM2_PARAM_HOST_ROAMING,
2246 0, IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, "gethost_roaming" },
2247#endif /* PRISM2_NO_STATION_MODES */
2248 { PRISM2_PARAM_BCRX_STA_KEY,
2249 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "bcrx_sta_key" },
2250 { PRISM2_PARAM_BCRX_STA_KEY,
2251 0, IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, "getbcrx_sta_key" },
2252 { PRISM2_PARAM_IEEE_802_1X,
2253 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "ieee_802_1x" },
2254 { PRISM2_PARAM_IEEE_802_1X,
2255 0, IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, "getieee_802_1x" },
2256 { PRISM2_PARAM_ANTSEL_TX,
2257 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "antsel_tx" },
2258 { PRISM2_PARAM_ANTSEL_TX,
2259 0, IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, "getantsel_tx" },
2260 { PRISM2_PARAM_ANTSEL_RX,
2261 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "antsel_rx" },
2262 { PRISM2_PARAM_ANTSEL_RX,
2263 0, IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, "getantsel_rx" },
2264 { PRISM2_PARAM_MONITOR_TYPE,
2265 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "monitor_type" },
2266 { PRISM2_PARAM_MONITOR_TYPE,
2267 0, IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, "getmonitor_type" },
2268 { PRISM2_PARAM_WDS_TYPE,
2269 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "wds_type" },
2270 { PRISM2_PARAM_WDS_TYPE,
2271 0, IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, "getwds_type" },
2272 { PRISM2_PARAM_HOSTSCAN,
2273 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "hostscan" },
2274 { PRISM2_PARAM_HOSTSCAN,
2275 0, IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, "gethostscan" },
2276 { PRISM2_PARAM_AP_SCAN,
2277 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "ap_scan" },
2278 { PRISM2_PARAM_AP_SCAN,
2279 0, IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, "getap_scan" },
2280 { PRISM2_PARAM_ENH_SEC,
2281 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "enh_sec" },
2282 { PRISM2_PARAM_ENH_SEC,
2283 0, IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, "getenh_sec" },
2284#ifdef PRISM2_IO_DEBUG
2285 { PRISM2_PARAM_IO_DEBUG,
2286 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "io_debug" },
2287 { PRISM2_PARAM_IO_DEBUG,
2288 0, IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, "getio_debug" },
2289#endif /* PRISM2_IO_DEBUG */
2290 { PRISM2_PARAM_BASIC_RATES,
2291 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "basic_rates" },
2292 { PRISM2_PARAM_BASIC_RATES,
2293 0, IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, "getbasic_rates" },
2294 { PRISM2_PARAM_OPER_RATES,
2295 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "oper_rates" },
2296 { PRISM2_PARAM_OPER_RATES,
2297 0, IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, "getoper_rates" },
2298 { PRISM2_PARAM_HOSTAPD,
2299 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "hostapd" },
2300 { PRISM2_PARAM_HOSTAPD,
2301 0, IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, "gethostapd" },
2302 { PRISM2_PARAM_HOSTAPD_STA,
2303 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "hostapd_sta" },
2304 { PRISM2_PARAM_HOSTAPD_STA,
2305 0, IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, "gethostapd_sta" },
2306 { PRISM2_PARAM_WPA,
2307 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "wpa" },
2308 { PRISM2_PARAM_WPA,
2309 0, IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, "getwpa" },
2310 { PRISM2_PARAM_PRIVACY_INVOKED,
2311 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "privacy_invoked" },
2312 { PRISM2_PARAM_PRIVACY_INVOKED,
2313 0, IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, "getprivacy_invo" },
2314 { PRISM2_PARAM_TKIP_COUNTERMEASURES,
2315 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "tkip_countermea" },
2316 { PRISM2_PARAM_TKIP_COUNTERMEASURES,
2317 0, IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, "gettkip_counter" },
2318 { PRISM2_PARAM_DROP_UNENCRYPTED,
2319 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "drop_unencrypte" },
2320 { PRISM2_PARAM_DROP_UNENCRYPTED,
2321 0, IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, "getdrop_unencry" },
2322 { PRISM2_PARAM_SCAN_CHANNEL_MASK,
2323 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "scan_channels" },
2324 { PRISM2_PARAM_SCAN_CHANNEL_MASK,
2325 0, IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, "getscan_channel" },
2326};
2327
2328
2329static int prism2_ioctl_priv_inquire(struct net_device *dev, int *i)
2330{
2331 struct hostap_interface *iface;
2332 local_info_t *local;
2333
2334 iface = netdev_priv(dev);
2335 local = iface->local;
2336
2337 if (local->func->cmd(dev, HFA384X_CMDCODE_INQUIRE, *i, NULL, NULL))
2338 return -EOPNOTSUPP;
2339
2340 return 0;
2341}
2342
2343
2344static int prism2_ioctl_priv_prism2_param(struct net_device *dev,
2345 struct iw_request_info *info,
2346 void *wrqu, char *extra)
2347{
2348 struct hostap_interface *iface;
2349 local_info_t *local;
2350 int *i = (int *) extra;
2351 int param = *i;
2352 int value = *(i + 1);
2353 int ret = 0;
2354 u16 val;
2355
2356 iface = netdev_priv(dev);
2357 local = iface->local;
2358
2359 switch (param) {
2360 case PRISM2_PARAM_TXRATECTRL:
2361 local->fw_tx_rate_control = value;
2362 break;
2363
2364 case PRISM2_PARAM_BEACON_INT:
2365 if (hostap_set_word(dev, HFA384X_RID_CNFBEACONINT, value) ||
2366 local->func->reset_port(dev))
2367 ret = -EINVAL;
2368 else
2369 local->beacon_int = value;
2370 break;
2371
2372#ifndef PRISM2_NO_STATION_MODES
2373 case PRISM2_PARAM_PSEUDO_IBSS:
2374 if (value == local->pseudo_adhoc)
2375 break;
2376
2377 if (value != 0 && value != 1) {
2378 ret = -EINVAL;
2379 break;
2380 }
2381
2382 printk(KERN_DEBUG "prism2: %s: pseudo IBSS change %d -> %d\n",
2383 dev->name, local->pseudo_adhoc, value);
2384 local->pseudo_adhoc = value;
2385 if (local->iw_mode != IW_MODE_ADHOC)
2386 break;
2387
2388 if (hostap_set_word(dev, HFA384X_RID_CNFPORTTYPE,
2389 hostap_get_porttype(local))) {
2390 ret = -EOPNOTSUPP;
2391 break;
2392 }
2393
2394 if (local->func->reset_port(dev))
2395 ret = -EINVAL;
2396 break;
2397#endif /* PRISM2_NO_STATION_MODES */
2398
2399 case PRISM2_PARAM_ALC:
2400 printk(KERN_DEBUG "%s: %s ALC\n", dev->name,
2401 value == 0 ? "Disabling" : "Enabling");
2402 val = HFA384X_TEST_CFG_BIT_ALC;
2403 local->func->cmd(dev, HFA384X_CMDCODE_TEST |
2404 (HFA384X_TEST_CFG_BITS << 8),
2405 value == 0 ? 0 : 1, &val, NULL);
2406 break;
2407
2408 case PRISM2_PARAM_DUMP:
2409 local->frame_dump = value;
2410 break;
2411
2412 case PRISM2_PARAM_OTHER_AP_POLICY:
2413 if (value < 0 || value > 3) {
2414 ret = -EINVAL;
2415 break;
2416 }
2417 if (local->ap != NULL)
2418 local->ap->ap_policy = value;
2419 break;
2420
2421 case PRISM2_PARAM_AP_MAX_INACTIVITY:
2422 if (value < 0 || value > 7 * 24 * 60 * 60) {
2423 ret = -EINVAL;
2424 break;
2425 }
2426 if (local->ap != NULL)
2427 local->ap->max_inactivity = value * HZ;
2428 break;
2429
2430 case PRISM2_PARAM_AP_BRIDGE_PACKETS:
2431 if (local->ap != NULL)
2432 local->ap->bridge_packets = value;
2433 break;
2434
2435 case PRISM2_PARAM_DTIM_PERIOD:
2436 if (value < 0 || value > 65535) {
2437 ret = -EINVAL;
2438 break;
2439 }
2440 if (hostap_set_word(dev, HFA384X_RID_CNFOWNDTIMPERIOD, value)
2441 || local->func->reset_port(dev))
2442 ret = -EINVAL;
2443 else
2444 local->dtim_period = value;
2445 break;
2446
2447 case PRISM2_PARAM_AP_NULLFUNC_ACK:
2448 if (local->ap != NULL)
2449 local->ap->nullfunc_ack = value;
2450 break;
2451
2452 case PRISM2_PARAM_MAX_WDS:
2453 local->wds_max_connections = value;
2454 break;
2455
2456 case PRISM2_PARAM_AP_AUTOM_AP_WDS:
2457 if (local->ap != NULL) {
2458 if (!local->ap->autom_ap_wds && value) {
2459 /* add WDS link to all APs in STA table */
2460 hostap_add_wds_links(local);
2461 }
2462 local->ap->autom_ap_wds = value;
2463 }
2464 break;
2465
2466 case PRISM2_PARAM_AP_AUTH_ALGS:
2467 local->auth_algs = value;
2468 if (hostap_set_auth_algs(local))
2469 ret = -EINVAL;
2470 break;
2471
2472 case PRISM2_PARAM_MONITOR_ALLOW_FCSERR:
2473 local->monitor_allow_fcserr = value;
2474 break;
2475
2476 case PRISM2_PARAM_HOST_ENCRYPT:
2477 local->host_encrypt = value;
2478 if (hostap_set_encryption(local) ||
2479 local->func->reset_port(dev))
2480 ret = -EINVAL;
2481 break;
2482
2483 case PRISM2_PARAM_HOST_DECRYPT:
2484 local->host_decrypt = value;
2485 if (hostap_set_encryption(local) ||
2486 local->func->reset_port(dev))
2487 ret = -EINVAL;
2488 break;
2489
2490#ifndef PRISM2_NO_STATION_MODES
2491 case PRISM2_PARAM_HOST_ROAMING:
2492 if (value < 0 || value > 2) {
2493 ret = -EINVAL;
2494 break;
2495 }
2496 local->host_roaming = value;
2497 if (hostap_set_roaming(local) || local->func->reset_port(dev))
2498 ret = -EINVAL;
2499 break;
2500#endif /* PRISM2_NO_STATION_MODES */
2501
2502 case PRISM2_PARAM_BCRX_STA_KEY:
2503 local->bcrx_sta_key = value;
2504 break;
2505
2506 case PRISM2_PARAM_IEEE_802_1X:
2507 local->ieee_802_1x = value;
2508 break;
2509
2510 case PRISM2_PARAM_ANTSEL_TX:
2511 if (value < 0 || value > HOSTAP_ANTSEL_HIGH) {
2512 ret = -EINVAL;
2513 break;
2514 }
2515 local->antsel_tx = value;
2516 hostap_set_antsel(local);
2517 break;
2518
2519 case PRISM2_PARAM_ANTSEL_RX:
2520 if (value < 0 || value > HOSTAP_ANTSEL_HIGH) {
2521 ret = -EINVAL;
2522 break;
2523 }
2524 local->antsel_rx = value;
2525 hostap_set_antsel(local);
2526 break;
2527
2528 case PRISM2_PARAM_MONITOR_TYPE:
2529 if (value != PRISM2_MONITOR_80211 &&
2530 value != PRISM2_MONITOR_CAPHDR &&
2531 value != PRISM2_MONITOR_PRISM) {
2532 ret = -EINVAL;
2533 break;
2534 }
2535 local->monitor_type = value;
2536 if (local->iw_mode == IW_MODE_MONITOR)
2537 hostap_monitor_set_type(local);
2538 break;
2539
2540 case PRISM2_PARAM_WDS_TYPE:
2541 local->wds_type = value;
2542 break;
2543
2544 case PRISM2_PARAM_HOSTSCAN:
2545 {
2546 struct hfa384x_hostscan_request scan_req;
2547 u16 rate;
2548
2549 memset(&scan_req, 0, sizeof(scan_req));
2550 scan_req.channel_list = __constant_cpu_to_le16(0x3fff);
2551 switch (value) {
2552 case 1: rate = HFA384X_RATES_1MBPS; break;
2553 case 2: rate = HFA384X_RATES_2MBPS; break;
2554 case 3: rate = HFA384X_RATES_5MBPS; break;
2555 case 4: rate = HFA384X_RATES_11MBPS; break;
2556 default: rate = HFA384X_RATES_1MBPS; break;
2557 }
2558 scan_req.txrate = cpu_to_le16(rate);
2559 /* leave SSID empty to accept all SSIDs */
2560
2561 if (local->iw_mode == IW_MODE_MASTER) {
2562 if (hostap_set_word(dev, HFA384X_RID_CNFPORTTYPE,
2563 HFA384X_PORTTYPE_BSS) ||
2564 local->func->reset_port(dev))
2565 printk(KERN_DEBUG "Leaving Host AP mode "
2566 "for HostScan failed\n");
2567 }
2568
2569 if (local->func->set_rid(dev, HFA384X_RID_HOSTSCAN, &scan_req,
2570 sizeof(scan_req))) {
2571 printk(KERN_DEBUG "HOSTSCAN failed\n");
2572 ret = -EINVAL;
2573 }
2574 if (local->iw_mode == IW_MODE_MASTER) {
2575 wait_queue_t __wait;
2576 init_waitqueue_entry(&__wait, current);
2577 add_wait_queue(&local->hostscan_wq, &__wait);
2578 set_current_state(TASK_INTERRUPTIBLE);
2579 schedule_timeout(HZ);
2580 if (signal_pending(current))
2581 ret = -EINTR;
2582 set_current_state(TASK_RUNNING);
2583 remove_wait_queue(&local->hostscan_wq, &__wait);
2584
2585 if (hostap_set_word(dev, HFA384X_RID_CNFPORTTYPE,
2586 HFA384X_PORTTYPE_HOSTAP) ||
2587 local->func->reset_port(dev))
2588 printk(KERN_DEBUG "Returning to Host AP mode "
2589 "after HostScan failed\n");
2590 }
2591 break;
2592 }
2593
2594 case PRISM2_PARAM_AP_SCAN:
2595 local->passive_scan_interval = value;
2596 if (timer_pending(&local->passive_scan_timer))
2597 del_timer(&local->passive_scan_timer);
2598 if (value > 0) {
2599 local->passive_scan_timer.expires = jiffies +
2600 local->passive_scan_interval * HZ;
2601 add_timer(&local->passive_scan_timer);
2602 }
2603 break;
2604
2605 case PRISM2_PARAM_ENH_SEC:
2606 if (value < 0 || value > 3) {
2607 ret = -EINVAL;
2608 break;
2609 }
2610 local->enh_sec = value;
2611 if (hostap_set_word(dev, HFA384X_RID_CNFENHSECURITY,
2612 local->enh_sec) ||
2613 local->func->reset_port(dev)) {
2614 printk(KERN_INFO "%s: cnfEnhSecurity requires STA f/w "
2615 "1.6.3 or newer\n", dev->name);
2616 ret = -EOPNOTSUPP;
2617 }
2618 break;
2619
2620#ifdef PRISM2_IO_DEBUG
2621 case PRISM2_PARAM_IO_DEBUG:
2622 local->io_debug_enabled = value;
2623 break;
2624#endif /* PRISM2_IO_DEBUG */
2625
2626 case PRISM2_PARAM_BASIC_RATES:
2627 if ((value & local->tx_rate_control) != value || value == 0) {
2628 printk(KERN_INFO "%s: invalid basic rate set - basic "
2629 "rates must be in supported rate set\n",
2630 dev->name);
2631 ret = -EINVAL;
2632 break;
2633 }
2634 local->basic_rates = value;
2635 if (hostap_set_word(dev, HFA384X_RID_CNFBASICRATES,
2636 local->basic_rates) ||
2637 local->func->reset_port(dev))
2638 ret = -EINVAL;
2639 break;
2640
2641 case PRISM2_PARAM_OPER_RATES:
2642 local->tx_rate_control = value;
2643 if (hostap_set_rate(dev))
2644 ret = -EINVAL;
2645 break;
2646
2647 case PRISM2_PARAM_HOSTAPD:
2648 ret = hostap_set_hostapd(local, value, 1);
2649 break;
2650
2651 case PRISM2_PARAM_HOSTAPD_STA:
2652 ret = hostap_set_hostapd_sta(local, value, 1);
2653 break;
2654
2655 case PRISM2_PARAM_WPA:
2656 local->wpa = value;
2657 if (local->sta_fw_ver < PRISM2_FW_VER(1,7,0))
2658 ret = -EOPNOTSUPP;
2659 else if (hostap_set_word(dev, HFA384X_RID_SSNHANDLINGMODE,
2660 value ? 1 : 0))
2661 ret = -EINVAL;
2662 break;
2663
2664 case PRISM2_PARAM_PRIVACY_INVOKED:
2665 local->privacy_invoked = value;
2666 if (hostap_set_encryption(local) ||
2667 local->func->reset_port(dev))
2668 ret = -EINVAL;
2669 break;
2670
2671 case PRISM2_PARAM_TKIP_COUNTERMEASURES:
2672 local->tkip_countermeasures = value;
2673 break;
2674
2675 case PRISM2_PARAM_DROP_UNENCRYPTED:
2676 local->drop_unencrypted = value;
2677 break;
2678
2679 case PRISM2_PARAM_SCAN_CHANNEL_MASK:
2680 local->scan_channel_mask = value;
2681 break;
2682
2683 default:
2684 printk(KERN_DEBUG "%s: prism2_param: unknown param %d\n",
2685 dev->name, param);
2686 ret = -EOPNOTSUPP;
2687 break;
2688 }
2689
2690 return ret;
2691}
2692
2693
2694static int prism2_ioctl_priv_get_prism2_param(struct net_device *dev,
2695 struct iw_request_info *info,
2696 void *wrqu, char *extra)
2697{
2698 struct hostap_interface *iface;
2699 local_info_t *local;
2700 int *param = (int *) extra;
2701 int ret = 0;
2702
2703 iface = netdev_priv(dev);
2704 local = iface->local;
2705
2706 switch (*param) {
2707 case PRISM2_PARAM_TXRATECTRL:
2708 *param = local->fw_tx_rate_control;
2709 break;
2710
2711 case PRISM2_PARAM_BEACON_INT:
2712 *param = local->beacon_int;
2713 break;
2714
2715 case PRISM2_PARAM_PSEUDO_IBSS:
2716 *param = local->pseudo_adhoc;
2717 break;
2718
2719 case PRISM2_PARAM_ALC:
2720 ret = -EOPNOTSUPP; /* FIX */
2721 break;
2722
2723 case PRISM2_PARAM_DUMP:
2724 *param = local->frame_dump;
2725 break;
2726
2727 case PRISM2_PARAM_OTHER_AP_POLICY:
2728 if (local->ap != NULL)
2729 *param = local->ap->ap_policy;
2730 else
2731 ret = -EOPNOTSUPP;
2732 break;
2733
2734 case PRISM2_PARAM_AP_MAX_INACTIVITY:
2735 if (local->ap != NULL)
2736 *param = local->ap->max_inactivity / HZ;
2737 else
2738 ret = -EOPNOTSUPP;
2739 break;
2740
2741 case PRISM2_PARAM_AP_BRIDGE_PACKETS:
2742 if (local->ap != NULL)
2743 *param = local->ap->bridge_packets;
2744 else
2745 ret = -EOPNOTSUPP;
2746 break;
2747
2748 case PRISM2_PARAM_DTIM_PERIOD:
2749 *param = local->dtim_period;
2750 break;
2751
2752 case PRISM2_PARAM_AP_NULLFUNC_ACK:
2753 if (local->ap != NULL)
2754 *param = local->ap->nullfunc_ack;
2755 else
2756 ret = -EOPNOTSUPP;
2757 break;
2758
2759 case PRISM2_PARAM_MAX_WDS:
2760 *param = local->wds_max_connections;
2761 break;
2762
2763 case PRISM2_PARAM_AP_AUTOM_AP_WDS:
2764 if (local->ap != NULL)
2765 *param = local->ap->autom_ap_wds;
2766 else
2767 ret = -EOPNOTSUPP;
2768 break;
2769
2770 case PRISM2_PARAM_AP_AUTH_ALGS:
2771 *param = local->auth_algs;
2772 break;
2773
2774 case PRISM2_PARAM_MONITOR_ALLOW_FCSERR:
2775 *param = local->monitor_allow_fcserr;
2776 break;
2777
2778 case PRISM2_PARAM_HOST_ENCRYPT:
2779 *param = local->host_encrypt;
2780 break;
2781
2782 case PRISM2_PARAM_HOST_DECRYPT:
2783 *param = local->host_decrypt;
2784 break;
2785
2786 case PRISM2_PARAM_HOST_ROAMING:
2787 *param = local->host_roaming;
2788 break;
2789
2790 case PRISM2_PARAM_BCRX_STA_KEY:
2791 *param = local->bcrx_sta_key;
2792 break;
2793
2794 case PRISM2_PARAM_IEEE_802_1X:
2795 *param = local->ieee_802_1x;
2796 break;
2797
2798 case PRISM2_PARAM_ANTSEL_TX:
2799 *param = local->antsel_tx;
2800 break;
2801
2802 case PRISM2_PARAM_ANTSEL_RX:
2803 *param = local->antsel_rx;
2804 break;
2805
2806 case PRISM2_PARAM_MONITOR_TYPE:
2807 *param = local->monitor_type;
2808 break;
2809
2810 case PRISM2_PARAM_WDS_TYPE:
2811 *param = local->wds_type;
2812 break;
2813
2814 case PRISM2_PARAM_HOSTSCAN:
2815 ret = -EOPNOTSUPP;
2816 break;
2817
2818 case PRISM2_PARAM_AP_SCAN:
2819 *param = local->passive_scan_interval;
2820 break;
2821
2822 case PRISM2_PARAM_ENH_SEC:
2823 *param = local->enh_sec;
2824 break;
2825
2826#ifdef PRISM2_IO_DEBUG
2827 case PRISM2_PARAM_IO_DEBUG:
2828 *param = local->io_debug_enabled;
2829 break;
2830#endif /* PRISM2_IO_DEBUG */
2831
2832 case PRISM2_PARAM_BASIC_RATES:
2833 *param = local->basic_rates;
2834 break;
2835
2836 case PRISM2_PARAM_OPER_RATES:
2837 *param = local->tx_rate_control;
2838 break;
2839
2840 case PRISM2_PARAM_HOSTAPD:
2841 *param = local->hostapd;
2842 break;
2843
2844 case PRISM2_PARAM_HOSTAPD_STA:
2845 *param = local->hostapd_sta;
2846 break;
2847
2848 case PRISM2_PARAM_WPA:
2849 if (local->sta_fw_ver < PRISM2_FW_VER(1,7,0))
2850 ret = -EOPNOTSUPP;
2851 *param = local->wpa;
2852 break;
2853
2854 case PRISM2_PARAM_PRIVACY_INVOKED:
2855 *param = local->privacy_invoked;
2856 break;
2857
2858 case PRISM2_PARAM_TKIP_COUNTERMEASURES:
2859 *param = local->tkip_countermeasures;
2860 break;
2861
2862 case PRISM2_PARAM_DROP_UNENCRYPTED:
2863 *param = local->drop_unencrypted;
2864 break;
2865
2866 case PRISM2_PARAM_SCAN_CHANNEL_MASK:
2867 *param = local->scan_channel_mask;
2868 break;
2869
2870 default:
2871 printk(KERN_DEBUG "%s: get_prism2_param: unknown param %d\n",
2872 dev->name, *param);
2873 ret = -EOPNOTSUPP;
2874 break;
2875 }
2876
2877 return ret;
2878}
2879
2880
2881static int prism2_ioctl_priv_readmif(struct net_device *dev,
2882 struct iw_request_info *info,
2883 void *wrqu, char *extra)
2884{
2885 struct hostap_interface *iface;
2886 local_info_t *local;
2887 u16 resp0;
2888
2889 iface = netdev_priv(dev);
2890 local = iface->local;
2891
2892 if (local->func->cmd(dev, HFA384X_CMDCODE_READMIF, *extra, NULL,
2893 &resp0))
2894 return -EOPNOTSUPP;
2895 else
2896 *extra = resp0;
2897
2898 return 0;
2899}
2900
2901
2902static int prism2_ioctl_priv_writemif(struct net_device *dev,
2903 struct iw_request_info *info,
2904 void *wrqu, char *extra)
2905{
2906 struct hostap_interface *iface;
2907 local_info_t *local;
2908 u16 cr, val;
2909
2910 iface = netdev_priv(dev);
2911 local = iface->local;
2912
2913 cr = *extra;
2914 val = *(extra + 1);
2915 if (local->func->cmd(dev, HFA384X_CMDCODE_WRITEMIF, cr, &val, NULL))
2916 return -EOPNOTSUPP;
2917
2918 return 0;
2919}
2920
2921
2922static int prism2_ioctl_priv_monitor(struct net_device *dev, int *i)
2923{
2924 struct hostap_interface *iface;
2925 local_info_t *local;
2926 int ret = 0;
2927 u32 mode;
2928
2929 iface = netdev_priv(dev);
2930 local = iface->local;
2931
2932 printk(KERN_DEBUG "%s: process %d (%s) used deprecated iwpriv monitor "
2933 "- update software to use iwconfig mode monitor\n",
2934 dev->name, current->pid, current->comm);
2935
2936 /* Backward compatibility code - this can be removed at some point */
2937
2938 if (*i == 0) {
2939 /* Disable monitor mode - old mode was not saved, so go to
2940 * Master mode */
2941 mode = IW_MODE_MASTER;
2942 ret = prism2_ioctl_siwmode(dev, NULL, &mode, NULL);
2943 } else if (*i == 1) {
2944 /* netlink socket mode is not supported anymore since it did
2945 * not separate different devices from each other and was not
2946 * best method for delivering large amount of packets to
2947 * user space */
2948 ret = -EOPNOTSUPP;
2949 } else if (*i == 2 || *i == 3) {
2950 switch (*i) {
2951 case 2:
2952 local->monitor_type = PRISM2_MONITOR_80211;
2953 break;
2954 case 3:
2955 local->monitor_type = PRISM2_MONITOR_PRISM;
2956 break;
2957 }
2958 mode = IW_MODE_MONITOR;
2959 ret = prism2_ioctl_siwmode(dev, NULL, &mode, NULL);
2960 hostap_monitor_mode_enable(local);
2961 } else
2962 ret = -EINVAL;
2963
2964 return ret;
2965}
2966
2967
2968static int prism2_ioctl_priv_reset(struct net_device *dev, int *i)
2969{
2970 struct hostap_interface *iface;
2971 local_info_t *local;
2972
2973 iface = netdev_priv(dev);
2974 local = iface->local;
2975
2976 printk(KERN_DEBUG "%s: manual reset request(%d)\n", dev->name, *i);
2977 switch (*i) {
2978 case 0:
2979 /* Disable and enable card */
2980 local->func->hw_shutdown(dev, 1);
2981 local->func->hw_config(dev, 0);
2982 break;
2983
2984 case 1:
2985 /* COR sreset */
2986 local->func->hw_reset(dev);
2987 break;
2988
2989 case 2:
2990 /* Disable and enable port 0 */
2991 local->func->reset_port(dev);
2992 break;
2993
2994 case 3:
2995 prism2_sta_deauth(local, WLAN_REASON_DEAUTH_LEAVING);
2996 if (local->func->cmd(dev, HFA384X_CMDCODE_DISABLE, 0, NULL,
2997 NULL))
2998 return -EINVAL;
2999 break;
3000
3001 case 4:
3002 if (local->func->cmd(dev, HFA384X_CMDCODE_ENABLE, 0, NULL,
3003 NULL))
3004 return -EINVAL;
3005 break;
3006
3007 default:
3008 printk(KERN_DEBUG "Unknown reset request %d\n", *i);
3009 return -EOPNOTSUPP;
3010 }
3011
3012 return 0;
3013}
3014
3015
3016static int prism2_ioctl_priv_set_rid_word(struct net_device *dev, int *i)
3017{
3018 int rid = *i;
3019 int value = *(i + 1);
3020
3021 printk(KERN_DEBUG "%s: Set RID[0x%X] = %d\n", dev->name, rid, value);
3022
3023 if (hostap_set_word(dev, rid, value))
3024 return -EINVAL;
3025
3026 return 0;
3027}
3028
3029
3030#ifndef PRISM2_NO_KERNEL_IEEE80211_MGMT
3031static int ap_mac_cmd_ioctl(local_info_t *local, int *cmd)
3032{
3033 int ret = 0;
3034
3035 switch (*cmd) {
3036 case AP_MAC_CMD_POLICY_OPEN:
3037 local->ap->mac_restrictions.policy = MAC_POLICY_OPEN;
3038 break;
3039 case AP_MAC_CMD_POLICY_ALLOW:
3040 local->ap->mac_restrictions.policy = MAC_POLICY_ALLOW;
3041 break;
3042 case AP_MAC_CMD_POLICY_DENY:
3043 local->ap->mac_restrictions.policy = MAC_POLICY_DENY;
3044 break;
3045 case AP_MAC_CMD_FLUSH:
3046 ap_control_flush_macs(&local->ap->mac_restrictions);
3047 break;
3048 case AP_MAC_CMD_KICKALL:
3049 ap_control_kickall(local->ap);
3050 hostap_deauth_all_stas(local->dev, local->ap, 0);
3051 break;
3052 default:
3053 ret = -EOPNOTSUPP;
3054 break;
3055 }
3056
3057 return ret;
3058}
3059#endif /* PRISM2_NO_KERNEL_IEEE80211_MGMT */
3060
3061
3062#ifdef PRISM2_DOWNLOAD_SUPPORT
3063static int prism2_ioctl_priv_download(local_info_t *local, struct iw_point *p)
3064{
3065 struct prism2_download_param *param;
3066 int ret = 0;
3067
3068 if (p->length < sizeof(struct prism2_download_param) ||
3069 p->length > 1024 || !p->pointer)
3070 return -EINVAL;
3071
3072 param = (struct prism2_download_param *)
3073 kmalloc(p->length, GFP_KERNEL);
3074 if (param == NULL)
3075 return -ENOMEM;
3076
3077 if (copy_from_user(param, p->pointer, p->length)) {
3078 ret = -EFAULT;
3079 goto out;
3080 }
3081
3082 if (p->length < sizeof(struct prism2_download_param) +
3083 param->num_areas * sizeof(struct prism2_download_area)) {
3084 ret = -EINVAL;
3085 goto out;
3086 }
3087
3088 ret = local->func->download(local, param);
3089
3090 out:
3091 if (param != NULL)
3092 kfree(param);
3093
3094 return ret;
3095}
3096#endif /* PRISM2_DOWNLOAD_SUPPORT */
3097
3098
3099static int prism2_set_genericelement(struct net_device *dev, u8 *elem,
3100 size_t len)
3101{
3102 struct hostap_interface *iface = dev->priv;
3103 local_info_t *local = iface->local;
3104 u8 *buf;
3105
3106 /*
3107 * Add 16-bit length in the beginning of the buffer because Prism2 RID
3108 * includes it.
3109 */
3110 buf = kmalloc(len + 2, GFP_KERNEL);
3111 if (buf == NULL)
3112 return -ENOMEM;
3113
3114 *((u16 *) buf) = cpu_to_le16(len);
3115 memcpy(buf + 2, elem, len);
3116
3117 kfree(local->generic_elem);
3118 local->generic_elem = buf;
3119 local->generic_elem_len = len + 2;
3120
3121 return local->func->set_rid(local->dev, HFA384X_RID_GENERICELEMENT,
3122 buf, len + 2);
3123}
3124
3125
3126static int prism2_ioctl_siwauth(struct net_device *dev,
3127 struct iw_request_info *info,
3128 struct iw_param *data, char *extra)
3129{
3130 struct hostap_interface *iface = dev->priv;
3131 local_info_t *local = iface->local;
3132
3133 switch (data->flags & IW_AUTH_INDEX) {
3134 case IW_AUTH_WPA_VERSION:
3135 case IW_AUTH_CIPHER_PAIRWISE:
3136 case IW_AUTH_CIPHER_GROUP:
3137 case IW_AUTH_KEY_MGMT:
3138 /*
3139 * Host AP driver does not use these parameters and allows
3140 * wpa_supplicant to control them internally.
3141 */
3142 break;
3143 case IW_AUTH_TKIP_COUNTERMEASURES:
3144 local->tkip_countermeasures = data->value;
3145 break;
3146 case IW_AUTH_DROP_UNENCRYPTED:
3147 local->drop_unencrypted = data->value;
3148 break;
3149 case IW_AUTH_80211_AUTH_ALG:
3150 local->auth_algs = data->value;
3151 break;
3152 case IW_AUTH_WPA_ENABLED:
3153 if (data->value == 0) {
3154 local->wpa = 0;
3155 if (local->sta_fw_ver < PRISM2_FW_VER(1,7,0))
3156 break;
3157 prism2_set_genericelement(dev, "", 0);
3158 local->host_roaming = 0;
3159 local->privacy_invoked = 0;
3160 if (hostap_set_word(dev, HFA384X_RID_SSNHANDLINGMODE,
3161 0) ||
3162 hostap_set_roaming(local) ||
3163 hostap_set_encryption(local) ||
3164 local->func->reset_port(dev))
3165 return -EINVAL;
3166 break;
3167 }
3168 if (local->sta_fw_ver < PRISM2_FW_VER(1,7,0))
3169 return -EOPNOTSUPP;
3170 local->host_roaming = 2;
3171 local->privacy_invoked = 1;
3172 local->wpa = 1;
3173 if (hostap_set_word(dev, HFA384X_RID_SSNHANDLINGMODE, 1) ||
3174 hostap_set_roaming(local) ||
3175 hostap_set_encryption(local) ||
3176 local->func->reset_port(dev))
3177 return -EINVAL;
3178 break;
3179 case IW_AUTH_RX_UNENCRYPTED_EAPOL:
3180 local->ieee_802_1x = data->value;
3181 break;
3182 case IW_AUTH_PRIVACY_INVOKED:
3183 local->privacy_invoked = data->value;
3184 break;
3185 default:
3186 return -EOPNOTSUPP;
3187 }
3188 return 0;
3189}
3190
3191
3192static int prism2_ioctl_giwauth(struct net_device *dev,
3193 struct iw_request_info *info,
3194 struct iw_param *data, char *extra)
3195{
3196 struct hostap_interface *iface = dev->priv;
3197 local_info_t *local = iface->local;
3198
3199 switch (data->flags & IW_AUTH_INDEX) {
3200 case IW_AUTH_WPA_VERSION:
3201 case IW_AUTH_CIPHER_PAIRWISE:
3202 case IW_AUTH_CIPHER_GROUP:
3203 case IW_AUTH_KEY_MGMT:
3204 /*
3205 * Host AP driver does not use these parameters and allows
3206 * wpa_supplicant to control them internally.
3207 */
3208 return -EOPNOTSUPP;
3209 case IW_AUTH_TKIP_COUNTERMEASURES:
3210 data->value = local->tkip_countermeasures;
3211 break;
3212 case IW_AUTH_DROP_UNENCRYPTED:
3213 data->value = local->drop_unencrypted;
3214 break;
3215 case IW_AUTH_80211_AUTH_ALG:
3216 data->value = local->auth_algs;
3217 break;
3218 case IW_AUTH_WPA_ENABLED:
3219 data->value = local->wpa;
3220 break;
3221 case IW_AUTH_RX_UNENCRYPTED_EAPOL:
3222 data->value = local->ieee_802_1x;
3223 break;
3224 default:
3225 return -EOPNOTSUPP;
3226 }
3227 return 0;
3228}
3229
3230
3231static int prism2_ioctl_siwencodeext(struct net_device *dev,
3232 struct iw_request_info *info,
3233 struct iw_point *erq, char *extra)
3234{
3235 struct hostap_interface *iface = dev->priv;
3236 local_info_t *local = iface->local;
3237 struct iw_encode_ext *ext = (struct iw_encode_ext *) extra;
3238 int i, ret = 0;
3239 struct ieee80211_crypto_ops *ops;
3240 struct ieee80211_crypt_data **crypt;
3241 void *sta_ptr;
3242 u8 *addr;
3243 const char *alg, *module;
3244
3245 i = erq->flags & IW_ENCODE_INDEX;
3246 if (i > WEP_KEYS)
3247 return -EINVAL;
3248 if (i < 1 || i > WEP_KEYS)
3249 i = local->tx_keyidx;
3250 else
3251 i--;
3252 if (i < 0 || i >= WEP_KEYS)
3253 return -EINVAL;
3254
3255 addr = ext->addr.sa_data;
3256 if (addr[0] == 0xff && addr[1] == 0xff && addr[2] == 0xff &&
3257 addr[3] == 0xff && addr[4] == 0xff && addr[5] == 0xff) {
3258 sta_ptr = NULL;
3259 crypt = &local->crypt[i];
3260 } else {
3261 if (i != 0)
3262 return -EINVAL;
3263 sta_ptr = ap_crypt_get_ptrs(local->ap, addr, 0, &crypt);
3264 if (sta_ptr == NULL) {
3265 if (local->iw_mode == IW_MODE_INFRA) {
3266 /*
3267 * TODO: add STA entry for the current AP so
3268 * that unicast key can be used. For now, this
3269 * is emulated by using default key idx 0.
3270 */
3271 i = 0;
3272 crypt = &local->crypt[i];
3273 } else
3274 return -EINVAL;
3275 }
3276 }
3277
3278 if ((erq->flags & IW_ENCODE_DISABLED) ||
3279 ext->alg == IW_ENCODE_ALG_NONE) {
3280 if (*crypt)
3281 prism2_crypt_delayed_deinit(local, crypt);
3282 goto done;
3283 }
3284
3285 switch (ext->alg) {
3286 case IW_ENCODE_ALG_WEP:
3287 alg = "WEP";
3288 module = "ieee80211_crypt_wep";
3289 break;
3290 case IW_ENCODE_ALG_TKIP:
3291 alg = "TKIP";
3292 module = "ieee80211_crypt_tkip";
3293 break;
3294 case IW_ENCODE_ALG_CCMP:
3295 alg = "CCMP";
3296 module = "ieee80211_crypt_ccmp";
3297 break;
3298 default:
3299 printk(KERN_DEBUG "%s: unsupported algorithm %d\n",
3300 local->dev->name, ext->alg);
3301 ret = -EOPNOTSUPP;
3302 goto done;
3303 }
3304
3305 ops = ieee80211_get_crypto_ops(alg);
3306 if (ops == NULL) {
3307 request_module(module);
3308 ops = ieee80211_get_crypto_ops(alg);
3309 }
3310 if (ops == NULL) {
3311 printk(KERN_DEBUG "%s: unknown crypto alg '%s'\n",
3312 local->dev->name, alg);
3313 ret = -EOPNOTSUPP;
3314 goto done;
3315 }
3316
3317 if (sta_ptr || ext->alg != IW_ENCODE_ALG_WEP) {
3318 /*
3319 * Per station encryption and other than WEP algorithms
3320 * require host-based encryption, so force them on
3321 * automatically.
3322 */
3323 local->host_decrypt = local->host_encrypt = 1;
3324 }
3325
3326 if (*crypt == NULL || (*crypt)->ops != ops) {
3327 struct ieee80211_crypt_data *new_crypt;
3328
3329 prism2_crypt_delayed_deinit(local, crypt);
3330
3331 new_crypt = (struct ieee80211_crypt_data *)
3332 kmalloc(sizeof(struct ieee80211_crypt_data),
3333 GFP_KERNEL);
3334 if (new_crypt == NULL) {
3335 ret = -ENOMEM;
3336 goto done;
3337 }
3338 memset(new_crypt, 0, sizeof(struct ieee80211_crypt_data));
3339 new_crypt->ops = ops;
3340 new_crypt->priv = new_crypt->ops->init(i);
3341 if (new_crypt->priv == NULL) {
3342 kfree(new_crypt);
3343 ret = -EINVAL;
3344 goto done;
3345 }
3346
3347 *crypt = new_crypt;
3348 }
3349
3350 /*
3351 * TODO: if ext_flags does not have IW_ENCODE_EXT_RX_SEQ_VALID, the
3352 * existing seq# should not be changed.
3353 * TODO: if ext_flags has IW_ENCODE_EXT_TX_SEQ_VALID, next TX seq#
3354 * should be changed to something else than zero.
3355 */
3356 if ((!(ext->ext_flags & IW_ENCODE_EXT_SET_TX_KEY) || ext->key_len > 0)
3357 && (*crypt)->ops->set_key &&
3358 (*crypt)->ops->set_key(ext->key, ext->key_len, ext->rx_seq,
3359 (*crypt)->priv) < 0) {
3360 printk(KERN_DEBUG "%s: key setting failed\n",
3361 local->dev->name);
3362 ret = -EINVAL;
3363 goto done;
3364 }
3365
3366 if (ext->ext_flags & IW_ENCODE_EXT_SET_TX_KEY) {
3367 if (!sta_ptr)
3368 local->tx_keyidx = i;
3369 else if (i) {
3370 ret = -EINVAL;
3371 goto done;
3372 }
3373 }
3374
3375
3376 if (sta_ptr == NULL && ext->key_len > 0) {
3377 int first = 1, j;
3378 for (j = 0; j < WEP_KEYS; j++) {
3379 if (j != i && local->crypt[j]) {
3380 first = 0;
3381 break;
3382 }
3383 }
3384 if (first)
3385 local->tx_keyidx = i;
3386 }
3387
3388 done:
3389 if (sta_ptr)
3390 hostap_handle_sta_release(sta_ptr);
3391
3392 local->open_wep = erq->flags & IW_ENCODE_OPEN;
3393
3394 /*
3395 * Do not reset port0 if card is in Managed mode since resetting will
3396 * generate new IEEE 802.11 authentication which may end up in looping
3397 * with IEEE 802.1X. Prism2 documentation seem to require port reset
3398 * after WEP configuration. However, keys are apparently changed at
3399 * least in Managed mode.
3400 */
3401 if (ret == 0 &&
3402 (hostap_set_encryption(local) ||
3403 (local->iw_mode != IW_MODE_INFRA &&
3404 local->func->reset_port(local->dev))))
3405 ret = -EINVAL;
3406
3407 return ret;
3408}
3409
3410
3411static int prism2_ioctl_giwencodeext(struct net_device *dev,
3412 struct iw_request_info *info,
3413 struct iw_point *erq, char *extra)
3414{
3415 struct hostap_interface *iface = dev->priv;
3416 local_info_t *local = iface->local;
3417 struct ieee80211_crypt_data **crypt;
3418 void *sta_ptr;
3419 int max_key_len, i;
3420 struct iw_encode_ext *ext = (struct iw_encode_ext *) extra;
3421 u8 *addr;
3422
3423 max_key_len = erq->length - sizeof(*ext);
3424 if (max_key_len < 0)
3425 return -EINVAL;
3426
3427 i = erq->flags & IW_ENCODE_INDEX;
3428 if (i < 1 || i > WEP_KEYS)
3429 i = local->tx_keyidx;
3430 else
3431 i--;
3432
3433 addr = ext->addr.sa_data;
3434 if (addr[0] == 0xff && addr[1] == 0xff && addr[2] == 0xff &&
3435 addr[3] == 0xff && addr[4] == 0xff && addr[5] == 0xff) {
3436 sta_ptr = NULL;
3437 crypt = &local->crypt[i];
3438 } else {
3439 i = 0;
3440 sta_ptr = ap_crypt_get_ptrs(local->ap, addr, 0, &crypt);
3441 if (sta_ptr == NULL)
3442 return -EINVAL;
3443 }
3444 erq->flags = i + 1;
3445 memset(ext, 0, sizeof(*ext));
3446
3447 if (*crypt == NULL || (*crypt)->ops == NULL) {
3448 ext->alg = IW_ENCODE_ALG_NONE;
3449 ext->key_len = 0;
3450 erq->flags |= IW_ENCODE_DISABLED;
3451 } else {
3452 if (strcmp((*crypt)->ops->name, "WEP") == 0)
3453 ext->alg = IW_ENCODE_ALG_WEP;
3454 else if (strcmp((*crypt)->ops->name, "TKIP") == 0)
3455 ext->alg = IW_ENCODE_ALG_TKIP;
3456 else if (strcmp((*crypt)->ops->name, "CCMP") == 0)
3457 ext->alg = IW_ENCODE_ALG_CCMP;
3458 else
3459 return -EINVAL;
3460
3461 if ((*crypt)->ops->get_key) {
3462 ext->key_len =
3463 (*crypt)->ops->get_key(ext->key,
3464 max_key_len,
3465 ext->tx_seq,
3466 (*crypt)->priv);
3467 if (ext->key_len &&
3468 (ext->alg == IW_ENCODE_ALG_TKIP ||
3469 ext->alg == IW_ENCODE_ALG_CCMP))
3470 ext->ext_flags |= IW_ENCODE_EXT_TX_SEQ_VALID;
3471 }
3472 }
3473
3474 if (sta_ptr)
3475 hostap_handle_sta_release(sta_ptr);
3476
3477 return 0;
3478}
3479
3480
3481static int prism2_ioctl_set_encryption(local_info_t *local,
3482 struct prism2_hostapd_param *param,
3483 int param_len)
3484{
3485 int ret = 0;
3486 struct ieee80211_crypto_ops *ops;
3487 struct ieee80211_crypt_data **crypt;
3488 void *sta_ptr;
3489
3490 param->u.crypt.err = 0;
3491 param->u.crypt.alg[HOSTAP_CRYPT_ALG_NAME_LEN - 1] = '\0';
3492
3493 if (param_len !=
3494 (int) ((char *) param->u.crypt.key - (char *) param) +
3495 param->u.crypt.key_len)
3496 return -EINVAL;
3497
3498 if (param->sta_addr[0] == 0xff && param->sta_addr[1] == 0xff &&
3499 param->sta_addr[2] == 0xff && param->sta_addr[3] == 0xff &&
3500 param->sta_addr[4] == 0xff && param->sta_addr[5] == 0xff) {
3501 if (param->u.crypt.idx >= WEP_KEYS)
3502 return -EINVAL;
3503 sta_ptr = NULL;
3504 crypt = &local->crypt[param->u.crypt.idx];
3505 } else {
3506 if (param->u.crypt.idx)
3507 return -EINVAL;
3508 sta_ptr = ap_crypt_get_ptrs(
3509 local->ap, param->sta_addr,
3510 (param->u.crypt.flags & HOSTAP_CRYPT_FLAG_PERMANENT),
3511 &crypt);
3512
3513 if (sta_ptr == NULL) {
3514 param->u.crypt.err = HOSTAP_CRYPT_ERR_UNKNOWN_ADDR;
3515 return -EINVAL;
3516 }
3517 }
3518
3519 if (strcmp(param->u.crypt.alg, "none") == 0) {
3520 if (crypt)
3521 prism2_crypt_delayed_deinit(local, crypt);
3522 goto done;
3523 }
3524
3525 ops = ieee80211_get_crypto_ops(param->u.crypt.alg);
3526 if (ops == NULL && strcmp(param->u.crypt.alg, "WEP") == 0) {
3527 request_module("ieee80211_crypt_wep");
3528 ops = ieee80211_get_crypto_ops(param->u.crypt.alg);
3529 } else if (ops == NULL && strcmp(param->u.crypt.alg, "TKIP") == 0) {
3530 request_module("ieee80211_crypt_tkip");
3531 ops = ieee80211_get_crypto_ops(param->u.crypt.alg);
3532 } else if (ops == NULL && strcmp(param->u.crypt.alg, "CCMP") == 0) {
3533 request_module("ieee80211_crypt_ccmp");
3534 ops = ieee80211_get_crypto_ops(param->u.crypt.alg);
3535 }
3536 if (ops == NULL) {
3537 printk(KERN_DEBUG "%s: unknown crypto alg '%s'\n",
3538 local->dev->name, param->u.crypt.alg);
3539 param->u.crypt.err = HOSTAP_CRYPT_ERR_UNKNOWN_ALG;
3540 ret = -EINVAL;
3541 goto done;
3542 }
3543
3544 /* station based encryption and other than WEP algorithms require
3545 * host-based encryption, so force them on automatically */
3546 local->host_decrypt = local->host_encrypt = 1;
3547
3548 if (*crypt == NULL || (*crypt)->ops != ops) {
3549 struct ieee80211_crypt_data *new_crypt;
3550
3551 prism2_crypt_delayed_deinit(local, crypt);
3552
3553 new_crypt = (struct ieee80211_crypt_data *)
3554 kmalloc(sizeof(struct ieee80211_crypt_data),
3555 GFP_KERNEL);
3556 if (new_crypt == NULL) {
3557 ret = -ENOMEM;
3558 goto done;
3559 }
3560 memset(new_crypt, 0, sizeof(struct ieee80211_crypt_data));
3561 new_crypt->ops = ops;
3562 new_crypt->priv = new_crypt->ops->init(param->u.crypt.idx);
3563 if (new_crypt->priv == NULL) {
3564 kfree(new_crypt);
3565 param->u.crypt.err =
3566 HOSTAP_CRYPT_ERR_CRYPT_INIT_FAILED;
3567 ret = -EINVAL;
3568 goto done;
3569 }
3570
3571 *crypt = new_crypt;
3572 }
3573
3574 if ((!(param->u.crypt.flags & HOSTAP_CRYPT_FLAG_SET_TX_KEY) ||
3575 param->u.crypt.key_len > 0) && (*crypt)->ops->set_key &&
3576 (*crypt)->ops->set_key(param->u.crypt.key,
3577 param->u.crypt.key_len, param->u.crypt.seq,
3578 (*crypt)->priv) < 0) {
3579 printk(KERN_DEBUG "%s: key setting failed\n",
3580 local->dev->name);
3581 param->u.crypt.err = HOSTAP_CRYPT_ERR_KEY_SET_FAILED;
3582 ret = -EINVAL;
3583 goto done;
3584 }
3585
3586 if (param->u.crypt.flags & HOSTAP_CRYPT_FLAG_SET_TX_KEY) {
3587 if (!sta_ptr)
3588 local->tx_keyidx = param->u.crypt.idx;
3589 else if (param->u.crypt.idx) {
3590 printk(KERN_DEBUG "%s: TX key idx setting failed\n",
3591 local->dev->name);
3592 param->u.crypt.err =
3593 HOSTAP_CRYPT_ERR_TX_KEY_SET_FAILED;
3594 ret = -EINVAL;
3595 goto done;
3596 }
3597 }
3598
3599 done:
3600 if (sta_ptr)
3601 hostap_handle_sta_release(sta_ptr);
3602
3603 /* Do not reset port0 if card is in Managed mode since resetting will
3604 * generate new IEEE 802.11 authentication which may end up in looping
3605 * with IEEE 802.1X. Prism2 documentation seem to require port reset
3606 * after WEP configuration. However, keys are apparently changed at
3607 * least in Managed mode. */
3608 if (ret == 0 &&
3609 (hostap_set_encryption(local) ||
3610 (local->iw_mode != IW_MODE_INFRA &&
3611 local->func->reset_port(local->dev)))) {
3612 param->u.crypt.err = HOSTAP_CRYPT_ERR_CARD_CONF_FAILED;
3613 return -EINVAL;
3614 }
3615
3616 return ret;
3617}
3618
3619
3620static int prism2_ioctl_get_encryption(local_info_t *local,
3621 struct prism2_hostapd_param *param,
3622 int param_len)
3623{
3624 struct ieee80211_crypt_data **crypt;
3625 void *sta_ptr;
3626 int max_key_len;
3627
3628 param->u.crypt.err = 0;
3629
3630 max_key_len = param_len -
3631 (int) ((char *) param->u.crypt.key - (char *) param);
3632 if (max_key_len < 0)
3633 return -EINVAL;
3634
3635 if (param->sta_addr[0] == 0xff && param->sta_addr[1] == 0xff &&
3636 param->sta_addr[2] == 0xff && param->sta_addr[3] == 0xff &&
3637 param->sta_addr[4] == 0xff && param->sta_addr[5] == 0xff) {
3638 sta_ptr = NULL;
3639 if (param->u.crypt.idx >= WEP_KEYS)
3640 param->u.crypt.idx = local->tx_keyidx;
3641 crypt = &local->crypt[param->u.crypt.idx];
3642 } else {
3643 param->u.crypt.idx = 0;
3644 sta_ptr = ap_crypt_get_ptrs(local->ap, param->sta_addr, 0,
3645 &crypt);
3646
3647 if (sta_ptr == NULL) {
3648 param->u.crypt.err = HOSTAP_CRYPT_ERR_UNKNOWN_ADDR;
3649 return -EINVAL;
3650 }
3651 }
3652
3653 if (*crypt == NULL || (*crypt)->ops == NULL) {
3654 memcpy(param->u.crypt.alg, "none", 5);
3655 param->u.crypt.key_len = 0;
3656 param->u.crypt.idx = 0xff;
3657 } else {
3658 strncpy(param->u.crypt.alg, (*crypt)->ops->name,
3659 HOSTAP_CRYPT_ALG_NAME_LEN);
3660 param->u.crypt.key_len = 0;
3661
3662 memset(param->u.crypt.seq, 0, 8);
3663 if ((*crypt)->ops->get_key) {
3664 param->u.crypt.key_len =
3665 (*crypt)->ops->get_key(param->u.crypt.key,
3666 max_key_len,
3667 param->u.crypt.seq,
3668 (*crypt)->priv);
3669 }
3670 }
3671
3672 if (sta_ptr)
3673 hostap_handle_sta_release(sta_ptr);
3674
3675 return 0;
3676}
3677
3678
3679static int prism2_ioctl_get_rid(local_info_t *local,
3680 struct prism2_hostapd_param *param,
3681 int param_len)
3682{
3683 int max_len, res;
3684
3685 max_len = param_len - PRISM2_HOSTAPD_RID_HDR_LEN;
3686 if (max_len < 0)
3687 return -EINVAL;
3688
3689 res = local->func->get_rid(local->dev, param->u.rid.rid,
3690 param->u.rid.data, param->u.rid.len, 0);
3691 if (res >= 0) {
3692 param->u.rid.len = res;
3693 return 0;
3694 }
3695
3696 return res;
3697}
3698
3699
3700static int prism2_ioctl_set_rid(local_info_t *local,
3701 struct prism2_hostapd_param *param,
3702 int param_len)
3703{
3704 int max_len;
3705
3706 max_len = param_len - PRISM2_HOSTAPD_RID_HDR_LEN;
3707 if (max_len < 0 || max_len < param->u.rid.len)
3708 return -EINVAL;
3709
3710 return local->func->set_rid(local->dev, param->u.rid.rid,
3711 param->u.rid.data, param->u.rid.len);
3712}
3713
3714
3715static int prism2_ioctl_set_assoc_ap_addr(local_info_t *local,
3716 struct prism2_hostapd_param *param,
3717 int param_len)
3718{
3719 printk(KERN_DEBUG "%ssta: associated as client with AP " MACSTR "\n",
3720 local->dev->name, MAC2STR(param->sta_addr));
3721 memcpy(local->assoc_ap_addr, param->sta_addr, ETH_ALEN);
3722 return 0;
3723}
3724
3725
3726static int prism2_ioctl_siwgenie(struct net_device *dev,
3727 struct iw_request_info *info,
3728 struct iw_point *data, char *extra)
3729{
3730 return prism2_set_genericelement(dev, extra, data->length);
3731}
3732
3733
3734static int prism2_ioctl_giwgenie(struct net_device *dev,
3735 struct iw_request_info *info,
3736 struct iw_point *data, char *extra)
3737{
3738 struct hostap_interface *iface = dev->priv;
3739 local_info_t *local = iface->local;
3740 int len = local->generic_elem_len - 2;
3741
3742 if (len <= 0 || local->generic_elem == NULL) {
3743 data->length = 0;
3744 return 0;
3745 }
3746
3747 if (data->length < len)
3748 return -E2BIG;
3749
3750 data->length = len;
3751 memcpy(extra, local->generic_elem + 2, len);
3752
3753 return 0;
3754}
3755
3756
3757static int prism2_ioctl_set_generic_element(local_info_t *local,
3758 struct prism2_hostapd_param *param,
3759 int param_len)
3760{
3761 int max_len, len;
3762
3763 len = param->u.generic_elem.len;
3764 max_len = param_len - PRISM2_HOSTAPD_GENERIC_ELEMENT_HDR_LEN;
3765 if (max_len < 0 || max_len < len)
3766 return -EINVAL;
3767
3768 return prism2_set_genericelement(local->dev,
3769 param->u.generic_elem.data, len);
3770}
3771
3772
3773static int prism2_ioctl_siwmlme(struct net_device *dev,
3774 struct iw_request_info *info,
3775 struct iw_point *data, char *extra)
3776{
3777 struct hostap_interface *iface = dev->priv;
3778 local_info_t *local = iface->local;
3779 struct iw_mlme *mlme = (struct iw_mlme *) extra;
3780 u16 reason;
3781
3782 reason = cpu_to_le16(mlme->reason_code);
3783
3784 switch (mlme->cmd) {
3785 case IW_MLME_DEAUTH:
3786 return prism2_sta_send_mgmt(local, mlme->addr.sa_data,
3787 IEEE80211_STYPE_DEAUTH,
3788 (u8 *) &reason, 2);
3789 case IW_MLME_DISASSOC:
3790 return prism2_sta_send_mgmt(local, mlme->addr.sa_data,
3791 IEEE80211_STYPE_DISASSOC,
3792 (u8 *) &reason, 2);
3793 default:
3794 return -EOPNOTSUPP;
3795 }
3796}
3797
3798
3799static int prism2_ioctl_mlme(local_info_t *local,
3800 struct prism2_hostapd_param *param)
3801{
3802 u16 reason;
3803
3804 reason = cpu_to_le16(param->u.mlme.reason_code);
3805 switch (param->u.mlme.cmd) {
3806 case MLME_STA_DEAUTH:
3807 return prism2_sta_send_mgmt(local, param->sta_addr,
3808 IEEE80211_STYPE_DEAUTH,
3809 (u8 *) &reason, 2);
3810 case MLME_STA_DISASSOC:
3811 return prism2_sta_send_mgmt(local, param->sta_addr,
3812 IEEE80211_STYPE_DISASSOC,
3813 (u8 *) &reason, 2);
3814 default:
3815 return -EOPNOTSUPP;
3816 }
3817}
3818
3819
3820static int prism2_ioctl_scan_req(local_info_t *local,
3821 struct prism2_hostapd_param *param)
3822{
3823#ifndef PRISM2_NO_STATION_MODES
3824 if ((local->iw_mode != IW_MODE_INFRA &&
3825 local->iw_mode != IW_MODE_ADHOC) ||
3826 (local->sta_fw_ver < PRISM2_FW_VER(1,3,1)))
3827 return -EOPNOTSUPP;
3828
3829 if (!local->dev_enabled)
3830 return -ENETDOWN;
3831
3832 return prism2_request_hostscan(local->dev, param->u.scan_req.ssid,
3833 param->u.scan_req.ssid_len);
3834#else /* PRISM2_NO_STATION_MODES */
3835 return -EOPNOTSUPP;
3836#endif /* PRISM2_NO_STATION_MODES */
3837}
3838
3839
3840static int prism2_ioctl_priv_hostapd(local_info_t *local, struct iw_point *p)
3841{
3842 struct prism2_hostapd_param *param;
3843 int ret = 0;
3844 int ap_ioctl = 0;
3845
3846 if (p->length < sizeof(struct prism2_hostapd_param) ||
3847 p->length > PRISM2_HOSTAPD_MAX_BUF_SIZE || !p->pointer)
3848 return -EINVAL;
3849
3850 param = (struct prism2_hostapd_param *) kmalloc(p->length, GFP_KERNEL);
3851 if (param == NULL)
3852 return -ENOMEM;
3853
3854 if (copy_from_user(param, p->pointer, p->length)) {
3855 ret = -EFAULT;
3856 goto out;
3857 }
3858
3859 switch (param->cmd) {
3860 case PRISM2_SET_ENCRYPTION:
3861 ret = prism2_ioctl_set_encryption(local, param, p->length);
3862 break;
3863 case PRISM2_GET_ENCRYPTION:
3864 ret = prism2_ioctl_get_encryption(local, param, p->length);
3865 break;
3866 case PRISM2_HOSTAPD_GET_RID:
3867 ret = prism2_ioctl_get_rid(local, param, p->length);
3868 break;
3869 case PRISM2_HOSTAPD_SET_RID:
3870 ret = prism2_ioctl_set_rid(local, param, p->length);
3871 break;
3872 case PRISM2_HOSTAPD_SET_ASSOC_AP_ADDR:
3873 ret = prism2_ioctl_set_assoc_ap_addr(local, param, p->length);
3874 break;
3875 case PRISM2_HOSTAPD_SET_GENERIC_ELEMENT:
3876 ret = prism2_ioctl_set_generic_element(local, param,
3877 p->length);
3878 break;
3879 case PRISM2_HOSTAPD_MLME:
3880 ret = prism2_ioctl_mlme(local, param);
3881 break;
3882 case PRISM2_HOSTAPD_SCAN_REQ:
3883 ret = prism2_ioctl_scan_req(local, param);
3884 break;
3885 default:
3886 ret = prism2_hostapd(local->ap, param);
3887 ap_ioctl = 1;
3888 break;
3889 }
3890
3891 if (ret == 1 || !ap_ioctl) {
3892 if (copy_to_user(p->pointer, param, p->length)) {
3893 ret = -EFAULT;
3894 goto out;
3895 } else if (ap_ioctl)
3896 ret = 0;
3897 }
3898
3899 out:
3900 if (param != NULL)
3901 kfree(param);
3902
3903 return ret;
3904}
3905
3906
3907static void prism2_get_drvinfo(struct net_device *dev,
3908 struct ethtool_drvinfo *info)
3909{
3910 struct hostap_interface *iface;
3911 local_info_t *local;
3912
3913 iface = netdev_priv(dev);
3914 local = iface->local;
3915
3916 strncpy(info->driver, "hostap", sizeof(info->driver) - 1);
3917 strncpy(info->version, PRISM2_VERSION,
3918 sizeof(info->version) - 1);
3919 snprintf(info->fw_version, sizeof(info->fw_version) - 1,
3920 "%d.%d.%d", (local->sta_fw_ver >> 16) & 0xff,
3921 (local->sta_fw_ver >> 8) & 0xff,
3922 local->sta_fw_ver & 0xff);
3923}
3924
3925static struct ethtool_ops prism2_ethtool_ops = {
3926 .get_drvinfo = prism2_get_drvinfo
3927};
3928
3929
3930/* Structures to export the Wireless Handlers */
3931
3932static const iw_handler prism2_handler[] =
3933{
3934 (iw_handler) NULL, /* SIOCSIWCOMMIT */
3935 (iw_handler) prism2_get_name, /* SIOCGIWNAME */
3936 (iw_handler) NULL, /* SIOCSIWNWID */
3937 (iw_handler) NULL, /* SIOCGIWNWID */
3938 (iw_handler) prism2_ioctl_siwfreq, /* SIOCSIWFREQ */
3939 (iw_handler) prism2_ioctl_giwfreq, /* SIOCGIWFREQ */
3940 (iw_handler) prism2_ioctl_siwmode, /* SIOCSIWMODE */
3941 (iw_handler) prism2_ioctl_giwmode, /* SIOCGIWMODE */
3942 (iw_handler) prism2_ioctl_siwsens, /* SIOCSIWSENS */
3943 (iw_handler) prism2_ioctl_giwsens, /* SIOCGIWSENS */
3944 (iw_handler) NULL /* not used */, /* SIOCSIWRANGE */
3945 (iw_handler) prism2_ioctl_giwrange, /* SIOCGIWRANGE */
3946 (iw_handler) NULL /* not used */, /* SIOCSIWPRIV */
3947 (iw_handler) NULL /* kernel code */, /* SIOCGIWPRIV */
3948 (iw_handler) NULL /* not used */, /* SIOCSIWSTATS */
3949 (iw_handler) NULL /* kernel code */, /* SIOCGIWSTATS */
3950 iw_handler_set_spy, /* SIOCSIWSPY */
3951 iw_handler_get_spy, /* SIOCGIWSPY */
3952 iw_handler_set_thrspy, /* SIOCSIWTHRSPY */
3953 iw_handler_get_thrspy, /* SIOCGIWTHRSPY */
3954 (iw_handler) prism2_ioctl_siwap, /* SIOCSIWAP */
3955 (iw_handler) prism2_ioctl_giwap, /* SIOCGIWAP */
3956 (iw_handler) prism2_ioctl_siwmlme, /* SIOCSIWMLME */
3957 (iw_handler) prism2_ioctl_giwaplist, /* SIOCGIWAPLIST */
3958 (iw_handler) prism2_ioctl_siwscan, /* SIOCSIWSCAN */
3959 (iw_handler) prism2_ioctl_giwscan, /* SIOCGIWSCAN */
3960 (iw_handler) prism2_ioctl_siwessid, /* SIOCSIWESSID */
3961 (iw_handler) prism2_ioctl_giwessid, /* SIOCGIWESSID */
3962 (iw_handler) prism2_ioctl_siwnickn, /* SIOCSIWNICKN */
3963 (iw_handler) prism2_ioctl_giwnickn, /* SIOCGIWNICKN */
3964 (iw_handler) NULL, /* -- hole -- */
3965 (iw_handler) NULL, /* -- hole -- */
3966 (iw_handler) prism2_ioctl_siwrate, /* SIOCSIWRATE */
3967 (iw_handler) prism2_ioctl_giwrate, /* SIOCGIWRATE */
3968 (iw_handler) prism2_ioctl_siwrts, /* SIOCSIWRTS */
3969 (iw_handler) prism2_ioctl_giwrts, /* SIOCGIWRTS */
3970 (iw_handler) prism2_ioctl_siwfrag, /* SIOCSIWFRAG */
3971 (iw_handler) prism2_ioctl_giwfrag, /* SIOCGIWFRAG */
3972 (iw_handler) prism2_ioctl_siwtxpow, /* SIOCSIWTXPOW */
3973 (iw_handler) prism2_ioctl_giwtxpow, /* SIOCGIWTXPOW */
3974 (iw_handler) prism2_ioctl_siwretry, /* SIOCSIWRETRY */
3975 (iw_handler) prism2_ioctl_giwretry, /* SIOCGIWRETRY */
3976 (iw_handler) prism2_ioctl_siwencode, /* SIOCSIWENCODE */
3977 (iw_handler) prism2_ioctl_giwencode, /* SIOCGIWENCODE */
3978 (iw_handler) prism2_ioctl_siwpower, /* SIOCSIWPOWER */
3979 (iw_handler) prism2_ioctl_giwpower, /* SIOCGIWPOWER */
3980 (iw_handler) NULL, /* -- hole -- */
3981 (iw_handler) NULL, /* -- hole -- */
3982 (iw_handler) prism2_ioctl_siwgenie, /* SIOCSIWGENIE */
3983 (iw_handler) prism2_ioctl_giwgenie, /* SIOCGIWGENIE */
3984 (iw_handler) prism2_ioctl_siwauth, /* SIOCSIWAUTH */
3985 (iw_handler) prism2_ioctl_giwauth, /* SIOCGIWAUTH */
3986 (iw_handler) prism2_ioctl_siwencodeext, /* SIOCSIWENCODEEXT */
3987 (iw_handler) prism2_ioctl_giwencodeext, /* SIOCGIWENCODEEXT */
3988 (iw_handler) NULL, /* SIOCSIWPMKSA */
3989 (iw_handler) NULL, /* -- hole -- */
3990};
3991
3992static const iw_handler prism2_private_handler[] =
3993{ /* SIOCIWFIRSTPRIV + */
3994 (iw_handler) prism2_ioctl_priv_prism2_param, /* 0 */
3995 (iw_handler) prism2_ioctl_priv_get_prism2_param, /* 1 */
3996 (iw_handler) prism2_ioctl_priv_writemif, /* 2 */
3997 (iw_handler) prism2_ioctl_priv_readmif, /* 3 */
3998};
3999
4000static const struct iw_handler_def hostap_iw_handler_def =
4001{
4002 .num_standard = sizeof(prism2_handler) / sizeof(iw_handler),
4003 .num_private = sizeof(prism2_private_handler) / sizeof(iw_handler),
4004 .num_private_args = sizeof(prism2_priv) / sizeof(struct iw_priv_args),
4005 .standard = (iw_handler *) prism2_handler,
4006 .private = (iw_handler *) prism2_private_handler,
4007 .private_args = (struct iw_priv_args *) prism2_priv,
4008 .get_wireless_stats = hostap_get_wireless_stats,
4009};
4010
4011
4012int hostap_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd)
4013{
4014 struct iwreq *wrq = (struct iwreq *) ifr;
4015 struct hostap_interface *iface;
4016 local_info_t *local;
4017 int ret = 0;
4018
4019 iface = netdev_priv(dev);
4020 local = iface->local;
4021
4022 switch (cmd) {
4023 /* Private ioctls (iwpriv) that have not yet been converted
4024 * into new wireless extensions API */
4025
4026 case PRISM2_IOCTL_INQUIRE:
4027 if (!capable(CAP_NET_ADMIN)) ret = -EPERM;
4028 else ret = prism2_ioctl_priv_inquire(dev, (int *) wrq->u.name);
4029 break;
4030
4031 case PRISM2_IOCTL_MONITOR:
4032 if (!capable(CAP_NET_ADMIN)) ret = -EPERM;
4033 else ret = prism2_ioctl_priv_monitor(dev, (int *) wrq->u.name);
4034 break;
4035
4036 case PRISM2_IOCTL_RESET:
4037 if (!capable(CAP_NET_ADMIN)) ret = -EPERM;
4038 else ret = prism2_ioctl_priv_reset(dev, (int *) wrq->u.name);
4039 break;
4040
4041 case PRISM2_IOCTL_WDS_ADD:
4042 if (!capable(CAP_NET_ADMIN)) ret = -EPERM;
4043 else ret = prism2_wds_add(local, wrq->u.ap_addr.sa_data, 1);
4044 break;
4045
4046 case PRISM2_IOCTL_WDS_DEL:
4047 if (!capable(CAP_NET_ADMIN)) ret = -EPERM;
4048 else ret = prism2_wds_del(local, wrq->u.ap_addr.sa_data, 1, 0);
4049 break;
4050
4051 case PRISM2_IOCTL_SET_RID_WORD:
4052 if (!capable(CAP_NET_ADMIN)) ret = -EPERM;
4053 else ret = prism2_ioctl_priv_set_rid_word(dev,
4054 (int *) wrq->u.name);
4055 break;
4056
4057#ifndef PRISM2_NO_KERNEL_IEEE80211_MGMT
4058 case PRISM2_IOCTL_MACCMD:
4059 if (!capable(CAP_NET_ADMIN)) ret = -EPERM;
4060 else ret = ap_mac_cmd_ioctl(local, (int *) wrq->u.name);
4061 break;
4062
4063 case PRISM2_IOCTL_ADDMAC:
4064 if (!capable(CAP_NET_ADMIN)) ret = -EPERM;
4065 else ret = ap_control_add_mac(&local->ap->mac_restrictions,
4066 wrq->u.ap_addr.sa_data);
4067 break;
4068 case PRISM2_IOCTL_DELMAC:
4069 if (!capable(CAP_NET_ADMIN)) ret = -EPERM;
4070 else ret = ap_control_del_mac(&local->ap->mac_restrictions,
4071 wrq->u.ap_addr.sa_data);
4072 break;
4073 case PRISM2_IOCTL_KICKMAC:
4074 if (!capable(CAP_NET_ADMIN)) ret = -EPERM;
4075 else ret = ap_control_kick_mac(local->ap, local->dev,
4076 wrq->u.ap_addr.sa_data);
4077 break;
4078#endif /* PRISM2_NO_KERNEL_IEEE80211_MGMT */
4079
4080
4081 /* Private ioctls that are not used with iwpriv;
4082 * in SIOCDEVPRIVATE range */
4083
4084#ifdef PRISM2_DOWNLOAD_SUPPORT
4085 case PRISM2_IOCTL_DOWNLOAD:
4086 if (!capable(CAP_NET_ADMIN)) ret = -EPERM;
4087 else ret = prism2_ioctl_priv_download(local, &wrq->u.data);
4088 break;
4089#endif /* PRISM2_DOWNLOAD_SUPPORT */
4090
4091 case PRISM2_IOCTL_HOSTAPD:
4092 if (!capable(CAP_NET_ADMIN)) ret = -EPERM;
4093 else ret = prism2_ioctl_priv_hostapd(local, &wrq->u.data);
4094 break;
4095
4096 default:
4097 ret = -EOPNOTSUPP;
4098 break;
4099 }
4100
4101 return ret;
4102}
diff --git a/drivers/net/wireless/hostap/hostap_pci.c b/drivers/net/wireless/hostap/hostap_pci.c
new file mode 100644
index 000000000000..4f567ef6178d
--- /dev/null
+++ b/drivers/net/wireless/hostap/hostap_pci.c
@@ -0,0 +1,473 @@
1#define PRISM2_PCI
2
3/* Host AP driver's support for Intersil Prism2.5 PCI cards is based on
4 * driver patches from Reyk Floeter <reyk@vantronix.net> and
5 * Andy Warner <andyw@pobox.com> */
6
7#include <linux/config.h>
8#include <linux/version.h>
9#include <linux/module.h>
10#include <linux/init.h>
11#include <linux/if.h>
12#include <linux/skbuff.h>
13#include <linux/netdevice.h>
14#include <linux/workqueue.h>
15#include <linux/wireless.h>
16#include <net/iw_handler.h>
17
18#include <linux/ioport.h>
19#include <linux/pci.h>
20#include <asm/io.h>
21
22#include "hostap_wlan.h"
23
24
25static char *version = PRISM2_VERSION " (Jouni Malinen <jkmaline@cc.hut.fi>)";
26static char *dev_info = "hostap_pci";
27
28
29MODULE_AUTHOR("Jouni Malinen");
30MODULE_DESCRIPTION("Support for Intersil Prism2.5-based 802.11 wireless LAN "
31 "PCI cards.");
32MODULE_SUPPORTED_DEVICE("Intersil Prism2.5-based WLAN PCI cards");
33MODULE_LICENSE("GPL");
34MODULE_VERSION(PRISM2_VERSION);
35
36
37/* struct local_info::hw_priv */
38struct hostap_pci_priv {
39 void __iomem *mem_start;
40};
41
42
43/* FIX: do we need mb/wmb/rmb with memory operations? */
44
45
46static struct pci_device_id prism2_pci_id_table[] __devinitdata = {
47 /* Intersil Prism3 ISL3872 11Mb/s WLAN Controller */
48 { 0x1260, 0x3872, PCI_ANY_ID, PCI_ANY_ID },
49 /* Intersil Prism2.5 ISL3874 11Mb/s WLAN Controller */
50 { 0x1260, 0x3873, PCI_ANY_ID, PCI_ANY_ID },
51 /* Samsung MagicLAN SWL-2210P */
52 { 0x167d, 0xa000, PCI_ANY_ID, PCI_ANY_ID },
53 { 0 }
54};
55
56
57#ifdef PRISM2_IO_DEBUG
58
59static inline void hfa384x_outb_debug(struct net_device *dev, int a, u8 v)
60{
61 struct hostap_interface *iface;
62 local_info_t *local;
63 unsigned long flags;
64
65 iface = netdev_priv(dev);
66 local = iface->local;
67
68 spin_lock_irqsave(&local->lock, flags);
69 prism2_io_debug_add(dev, PRISM2_IO_DEBUG_CMD_OUTB, a, v);
70 writeb(v, hw_priv->mem_start + a);
71 spin_unlock_irqrestore(&local->lock, flags);
72}
73
74static inline u8 hfa384x_inb_debug(struct net_device *dev, int a)
75{
76 struct hostap_interface *iface;
77 local_info_t *local;
78 unsigned long flags;
79 u8 v;
80
81 iface = netdev_priv(dev);
82 local = iface->local;
83
84 spin_lock_irqsave(&local->lock, flags);
85 v = readb(hw_priv->mem_start + a);
86 prism2_io_debug_add(dev, PRISM2_IO_DEBUG_CMD_INB, a, v);
87 spin_unlock_irqrestore(&local->lock, flags);
88 return v;
89}
90
91static inline void hfa384x_outw_debug(struct net_device *dev, int a, u16 v)
92{
93 struct hostap_interface *iface;
94 local_info_t *local;
95 unsigned long flags;
96
97 iface = netdev_priv(dev);
98 local = iface->local;
99
100 spin_lock_irqsave(&local->lock, flags);
101 prism2_io_debug_add(dev, PRISM2_IO_DEBUG_CMD_OUTW, a, v);
102 writew(v, hw_priv->mem_start + a);
103 spin_unlock_irqrestore(&local->lock, flags);
104}
105
106static inline u16 hfa384x_inw_debug(struct net_device *dev, int a)
107{
108 struct hostap_interface *iface;
109 local_info_t *local;
110 unsigned long flags;
111 u16 v;
112
113 iface = netdev_priv(dev);
114 local = iface->local;
115
116 spin_lock_irqsave(&local->lock, flags);
117 v = readw(hw_priv->mem_start + a);
118 prism2_io_debug_add(dev, PRISM2_IO_DEBUG_CMD_INW, a, v);
119 spin_unlock_irqrestore(&local->lock, flags);
120 return v;
121}
122
123#define HFA384X_OUTB(v,a) hfa384x_outb_debug(dev, (a), (v))
124#define HFA384X_INB(a) hfa384x_inb_debug(dev, (a))
125#define HFA384X_OUTW(v,a) hfa384x_outw_debug(dev, (a), (v))
126#define HFA384X_INW(a) hfa384x_inw_debug(dev, (a))
127#define HFA384X_OUTW_DATA(v,a) hfa384x_outw_debug(dev, (a), cpu_to_le16((v)))
128#define HFA384X_INW_DATA(a) (u16) le16_to_cpu(hfa384x_inw_debug(dev, (a)))
129
130#else /* PRISM2_IO_DEBUG */
131
132static inline void hfa384x_outb(struct net_device *dev, int a, u8 v)
133{
134 struct hostap_interface *iface;
135 struct hostap_pci_priv *hw_priv;
136 iface = netdev_priv(dev);
137 hw_priv = iface->local->hw_priv;
138 writeb(v, hw_priv->mem_start + a);
139}
140
141static inline u8 hfa384x_inb(struct net_device *dev, int a)
142{
143 struct hostap_interface *iface;
144 struct hostap_pci_priv *hw_priv;
145 iface = netdev_priv(dev);
146 hw_priv = iface->local->hw_priv;
147 return readb(hw_priv->mem_start + a);
148}
149
150static inline void hfa384x_outw(struct net_device *dev, int a, u16 v)
151{
152 struct hostap_interface *iface;
153 struct hostap_pci_priv *hw_priv;
154 iface = netdev_priv(dev);
155 hw_priv = iface->local->hw_priv;
156 writew(v, hw_priv->mem_start + a);
157}
158
159static inline u16 hfa384x_inw(struct net_device *dev, int a)
160{
161 struct hostap_interface *iface;
162 struct hostap_pci_priv *hw_priv;
163 iface = netdev_priv(dev);
164 hw_priv = iface->local->hw_priv;
165 return readw(hw_priv->mem_start + a);
166}
167
168#define HFA384X_OUTB(v,a) hfa384x_outb(dev, (a), (v))
169#define HFA384X_INB(a) hfa384x_inb(dev, (a))
170#define HFA384X_OUTW(v,a) hfa384x_outw(dev, (a), (v))
171#define HFA384X_INW(a) hfa384x_inw(dev, (a))
172#define HFA384X_OUTW_DATA(v,a) hfa384x_outw(dev, (a), cpu_to_le16((v)))
173#define HFA384X_INW_DATA(a) (u16) le16_to_cpu(hfa384x_inw(dev, (a)))
174
175#endif /* PRISM2_IO_DEBUG */
176
177
178static int hfa384x_from_bap(struct net_device *dev, u16 bap, void *buf,
179 int len)
180{
181 u16 d_off;
182 u16 *pos;
183
184 d_off = (bap == 1) ? HFA384X_DATA1_OFF : HFA384X_DATA0_OFF;
185 pos = (u16 *) buf;
186
187 for ( ; len > 1; len -= 2)
188 *pos++ = HFA384X_INW_DATA(d_off);
189
190 if (len & 1)
191 *((char *) pos) = HFA384X_INB(d_off);
192
193 return 0;
194}
195
196
197static int hfa384x_to_bap(struct net_device *dev, u16 bap, void *buf, int len)
198{
199 u16 d_off;
200 u16 *pos;
201
202 d_off = (bap == 1) ? HFA384X_DATA1_OFF : HFA384X_DATA0_OFF;
203 pos = (u16 *) buf;
204
205 for ( ; len > 1; len -= 2)
206 HFA384X_OUTW_DATA(*pos++, d_off);
207
208 if (len & 1)
209 HFA384X_OUTB(*((char *) pos), d_off);
210
211 return 0;
212}
213
214
215/* FIX: This might change at some point.. */
216#include "hostap_hw.c"
217
218static void prism2_pci_cor_sreset(local_info_t *local)
219{
220 struct net_device *dev = local->dev;
221 u16 reg;
222
223 reg = HFA384X_INB(HFA384X_PCICOR_OFF);
224 printk(KERN_DEBUG "%s: Original COR value: 0x%0x\n", dev->name, reg);
225
226 /* linux-wlan-ng uses extremely long hold and settle times for
227 * COR sreset. A comment in the driver code mentions that the long
228 * delays appear to be necessary. However, at least IBM 22P6901 seems
229 * to work fine with shorter delays.
230 *
231 * Longer delays can be configured by uncommenting following line: */
232/* #define PRISM2_PCI_USE_LONG_DELAYS */
233
234#ifdef PRISM2_PCI_USE_LONG_DELAYS
235 int i;
236
237 HFA384X_OUTW(reg | 0x0080, HFA384X_PCICOR_OFF);
238 mdelay(250);
239
240 HFA384X_OUTW(reg & ~0x0080, HFA384X_PCICOR_OFF);
241 mdelay(500);
242
243 /* Wait for f/w to complete initialization (CMD:BUSY == 0) */
244 i = 2000000 / 10;
245 while ((HFA384X_INW(HFA384X_CMD_OFF) & HFA384X_CMD_BUSY) && --i)
246 udelay(10);
247
248#else /* PRISM2_PCI_USE_LONG_DELAYS */
249
250 HFA384X_OUTW(reg | 0x0080, HFA384X_PCICOR_OFF);
251 mdelay(2);
252 HFA384X_OUTW(reg & ~0x0080, HFA384X_PCICOR_OFF);
253 mdelay(2);
254
255#endif /* PRISM2_PCI_USE_LONG_DELAYS */
256
257 if (HFA384X_INW(HFA384X_CMD_OFF) & HFA384X_CMD_BUSY) {
258 printk(KERN_DEBUG "%s: COR sreset timeout\n", dev->name);
259 }
260}
261
262
263static void prism2_pci_genesis_reset(local_info_t *local, int hcr)
264{
265 struct net_device *dev = local->dev;
266
267 HFA384X_OUTW(0x00C5, HFA384X_PCICOR_OFF);
268 mdelay(10);
269 HFA384X_OUTW(hcr, HFA384X_PCIHCR_OFF);
270 mdelay(10);
271 HFA384X_OUTW(0x0045, HFA384X_PCICOR_OFF);
272 mdelay(10);
273}
274
275
276static struct prism2_helper_functions prism2_pci_funcs =
277{
278 .card_present = NULL,
279 .cor_sreset = prism2_pci_cor_sreset,
280 .dev_open = NULL,
281 .dev_close = NULL,
282 .genesis_reset = prism2_pci_genesis_reset,
283 .hw_type = HOSTAP_HW_PCI,
284};
285
286
287static int prism2_pci_probe(struct pci_dev *pdev,
288 const struct pci_device_id *id)
289{
290 unsigned long phymem;
291 void __iomem *mem = NULL;
292 local_info_t *local = NULL;
293 struct net_device *dev = NULL;
294 static int cards_found /* = 0 */;
295 int irq_registered = 0;
296 struct hostap_interface *iface;
297 struct hostap_pci_priv *hw_priv;
298
299 hw_priv = kmalloc(sizeof(*hw_priv), GFP_KERNEL);
300 if (hw_priv == NULL)
301 return -ENOMEM;
302 memset(hw_priv, 0, sizeof(*hw_priv));
303
304 if (pci_enable_device(pdev))
305 return -EIO;
306
307 phymem = pci_resource_start(pdev, 0);
308
309 if (!request_mem_region(phymem, pci_resource_len(pdev, 0), "Prism2")) {
310 printk(KERN_ERR "prism2: Cannot reserve PCI memory region\n");
311 goto err_out_disable;
312 }
313
314 mem = ioremap(phymem, pci_resource_len(pdev, 0));
315 if (mem == NULL) {
316 printk(KERN_ERR "prism2: Cannot remap PCI memory region\n") ;
317 goto fail;
318 }
319
320 dev = prism2_init_local_data(&prism2_pci_funcs, cards_found,
321 &pdev->dev);
322 if (dev == NULL)
323 goto fail;
324 iface = netdev_priv(dev);
325 local = iface->local;
326 local->hw_priv = hw_priv;
327 cards_found++;
328
329 dev->irq = pdev->irq;
330 hw_priv->mem_start = mem;
331
332 prism2_pci_cor_sreset(local);
333
334 pci_set_drvdata(pdev, dev);
335
336 if (request_irq(dev->irq, prism2_interrupt, SA_SHIRQ, dev->name,
337 dev)) {
338 printk(KERN_WARNING "%s: request_irq failed\n", dev->name);
339 goto fail;
340 } else
341 irq_registered = 1;
342
343 if (!local->pri_only && prism2_hw_config(dev, 1)) {
344 printk(KERN_DEBUG "%s: hardware initialization failed\n",
345 dev_info);
346 goto fail;
347 }
348
349 printk(KERN_INFO "%s: Intersil Prism2.5 PCI: "
350 "mem=0x%lx, irq=%d\n", dev->name, phymem, dev->irq);
351
352 return hostap_hw_ready(dev);
353
354 fail:
355 kfree(hw_priv);
356
357 if (irq_registered && dev)
358 free_irq(dev->irq, dev);
359
360 if (mem)
361 iounmap(mem);
362
363 release_mem_region(phymem, pci_resource_len(pdev, 0));
364
365 err_out_disable:
366 pci_disable_device(pdev);
367 kfree(hw_priv);
368 if (local)
369 local->hw_priv = NULL;
370 prism2_free_local_data(dev);
371
372 return -ENODEV;
373}
374
375
376static void prism2_pci_remove(struct pci_dev *pdev)
377{
378 struct net_device *dev;
379 struct hostap_interface *iface;
380 void __iomem *mem_start;
381 struct hostap_pci_priv *hw_priv;
382
383 dev = pci_get_drvdata(pdev);
384 iface = netdev_priv(dev);
385 hw_priv = iface->local->hw_priv;
386
387 /* Reset the hardware, and ensure interrupts are disabled. */
388 prism2_pci_cor_sreset(iface->local);
389 hfa384x_disable_interrupts(dev);
390
391 if (dev->irq)
392 free_irq(dev->irq, dev);
393
394 mem_start = hw_priv->mem_start;
395 kfree(hw_priv);
396 iface->local->hw_priv = NULL;
397 prism2_free_local_data(dev);
398
399 iounmap(mem_start);
400
401 release_mem_region(pci_resource_start(pdev, 0),
402 pci_resource_len(pdev, 0));
403 pci_disable_device(pdev);
404}
405
406
407#ifdef CONFIG_PM
408static int prism2_pci_suspend(struct pci_dev *pdev, pm_message_t state)
409{
410 struct net_device *dev = pci_get_drvdata(pdev);
411
412 if (netif_running(dev)) {
413 netif_stop_queue(dev);
414 netif_device_detach(dev);
415 }
416 prism2_suspend(dev);
417 pci_save_state(pdev);
418 pci_disable_device(pdev);
419 pci_set_power_state(pdev, 3);
420
421 return 0;
422}
423
424static int prism2_pci_resume(struct pci_dev *pdev)
425{
426 struct net_device *dev = pci_get_drvdata(pdev);
427
428 pci_enable_device(pdev);
429 pci_restore_state(pdev);
430 prism2_hw_config(dev, 0);
431 if (netif_running(dev)) {
432 netif_device_attach(dev);
433 netif_start_queue(dev);
434 }
435
436 return 0;
437}
438#endif /* CONFIG_PM */
439
440
441MODULE_DEVICE_TABLE(pci, prism2_pci_id_table);
442
443static struct pci_driver prism2_pci_drv_id = {
444 .name = "prism2_pci",
445 .id_table = prism2_pci_id_table,
446 .probe = prism2_pci_probe,
447 .remove = prism2_pci_remove,
448#ifdef CONFIG_PM
449 .suspend = prism2_pci_suspend,
450 .resume = prism2_pci_resume,
451#endif /* CONFIG_PM */
452 /* Linux 2.4.6 added save_state and enable_wake that are not used here
453 */
454};
455
456
457static int __init init_prism2_pci(void)
458{
459 printk(KERN_INFO "%s: %s\n", dev_info, version);
460
461 return pci_register_driver(&prism2_pci_drv_id);
462}
463
464
465static void __exit exit_prism2_pci(void)
466{
467 pci_unregister_driver(&prism2_pci_drv_id);
468 printk(KERN_INFO "%s: Driver unloaded\n", dev_info);
469}
470
471
472module_init(init_prism2_pci);
473module_exit(exit_prism2_pci);
diff --git a/drivers/net/wireless/hostap/hostap_plx.c b/drivers/net/wireless/hostap/hostap_plx.c
new file mode 100644
index 000000000000..474ef83d813e
--- /dev/null
+++ b/drivers/net/wireless/hostap/hostap_plx.c
@@ -0,0 +1,645 @@
1#define PRISM2_PLX
2
3/* Host AP driver's support for PC Cards on PCI adapters using PLX9052 is
4 * based on:
5 * - Host AP driver patch from james@madingley.org
6 * - linux-wlan-ng driver, Copyright (C) AbsoluteValue Systems, Inc.
7 */
8
9
10#include <linux/config.h>
11#include <linux/version.h>
12#include <linux/module.h>
13#include <linux/init.h>
14#include <linux/if.h>
15#include <linux/skbuff.h>
16#include <linux/netdevice.h>
17#include <linux/workqueue.h>
18#include <linux/wireless.h>
19#include <net/iw_handler.h>
20
21#include <linux/ioport.h>
22#include <linux/pci.h>
23#include <asm/io.h>
24
25#include "hostap_wlan.h"
26
27
28static char *version = PRISM2_VERSION " (Jouni Malinen <jkmaline@cc.hut.fi>)";
29static char *dev_info = "hostap_plx";
30
31
32MODULE_AUTHOR("Jouni Malinen");
33MODULE_DESCRIPTION("Support for Intersil Prism2-based 802.11 wireless LAN "
34 "cards (PLX).");
35MODULE_SUPPORTED_DEVICE("Intersil Prism2-based WLAN cards (PLX)");
36MODULE_LICENSE("GPL");
37MODULE_VERSION(PRISM2_VERSION);
38
39
40static int ignore_cis;
41module_param(ignore_cis, int, 0444);
42MODULE_PARM_DESC(ignore_cis, "Do not verify manfid information in CIS");
43
44
45/* struct local_info::hw_priv */
46struct hostap_plx_priv {
47 void __iomem *attr_mem;
48 unsigned int cor_offset;
49};
50
51
52#define PLX_MIN_ATTR_LEN 512 /* at least 2 x 256 is needed for CIS */
53#define COR_SRESET 0x80
54#define COR_LEVLREQ 0x40
55#define COR_ENABLE_FUNC 0x01
56/* PCI Configuration Registers */
57#define PLX_PCIIPR 0x3d /* PCI Interrupt Pin */
58/* Local Configuration Registers */
59#define PLX_INTCSR 0x4c /* Interrupt Control/Status Register */
60#define PLX_INTCSR_PCI_INTEN BIT(6) /* PCI Interrupt Enable */
61#define PLX_CNTRL 0x50
62#define PLX_CNTRL_SERIAL_EEPROM_PRESENT BIT(28)
63
64
65#define PLXDEV(vendor,dev,str) { vendor, dev, PCI_ANY_ID, PCI_ANY_ID }
66
67static struct pci_device_id prism2_plx_id_table[] __devinitdata = {
68 PLXDEV(0x10b7, 0x7770, "3Com AirConnect PCI 777A"),
69 PLXDEV(0x111a, 0x1023, "Siemens SpeedStream SS1023"),
70 PLXDEV(0x126c, 0x8030, "Nortel emobility"),
71 PLXDEV(0x1385, 0x4100, "Netgear MA301"),
72 PLXDEV(0x15e8, 0x0130, "National Datacomm NCP130 (PLX9052)"),
73 PLXDEV(0x15e8, 0x0131, "National Datacomm NCP130 (TMD7160)"),
74 PLXDEV(0x1638, 0x1100, "Eumitcom WL11000"),
75 PLXDEV(0x16ab, 0x1101, "Global Sun Tech GL24110P (?)"),
76 PLXDEV(0x16ab, 0x1102, "Linksys WPC11 with WDT11"),
77 PLXDEV(0x16ab, 0x1103, "Longshine 8031"),
78 PLXDEV(0x16ec, 0x3685, "US Robotics USR2415"),
79 PLXDEV(0xec80, 0xec00, "Belkin F5D6000"),
80 { 0 }
81};
82
83
84/* Array of known Prism2/2.5 PC Card manufactured ids. If your card's manfid
85 * is not listed here, you will need to add it here to get the driver
86 * initialized. */
87static struct prism2_plx_manfid {
88 u16 manfid1, manfid2;
89} prism2_plx_known_manfids[] = {
90 { 0x000b, 0x7110 } /* D-Link DWL-650 Rev. P1 */,
91 { 0x000b, 0x7300 } /* Philips 802.11b WLAN PCMCIA */,
92 { 0x0101, 0x0777 } /* 3Com AirConnect PCI 777A */,
93 { 0x0126, 0x8000 } /* Proxim RangeLAN */,
94 { 0x0138, 0x0002 } /* Compaq WL100 */,
95 { 0x0156, 0x0002 } /* Intersil Prism II Ref. Design (and others) */,
96 { 0x026f, 0x030b } /* Buffalo WLI-CF-S11G */,
97 { 0x0274, 0x1612 } /* Linksys WPC11 Ver 2.5 */,
98 { 0x0274, 0x1613 } /* Linksys WPC11 Ver 3 */,
99 { 0x028a, 0x0002 } /* D-Link DRC-650 */,
100 { 0x0250, 0x0002 } /* Samsung SWL2000-N */,
101 { 0xc250, 0x0002 } /* EMTAC A2424i */,
102 { 0xd601, 0x0002 } /* Z-Com XI300 */,
103 { 0xd601, 0x0005 } /* Zcomax XI-325H 200mW */,
104 { 0, 0}
105};
106
107
108#ifdef PRISM2_IO_DEBUG
109
110static inline void hfa384x_outb_debug(struct net_device *dev, int a, u8 v)
111{
112 struct hostap_interface *iface;
113 local_info_t *local;
114 unsigned long flags;
115
116 iface = netdev_priv(dev);
117 local = iface->local;
118
119 spin_lock_irqsave(&local->lock, flags);
120 prism2_io_debug_add(dev, PRISM2_IO_DEBUG_CMD_OUTB, a, v);
121 outb(v, dev->base_addr + a);
122 spin_unlock_irqrestore(&local->lock, flags);
123}
124
125static inline u8 hfa384x_inb_debug(struct net_device *dev, int a)
126{
127 struct hostap_interface *iface;
128 local_info_t *local;
129 unsigned long flags;
130 u8 v;
131
132 iface = netdev_priv(dev);
133 local = iface->local;
134
135 spin_lock_irqsave(&local->lock, flags);
136 v = inb(dev->base_addr + a);
137 prism2_io_debug_add(dev, PRISM2_IO_DEBUG_CMD_INB, a, v);
138 spin_unlock_irqrestore(&local->lock, flags);
139 return v;
140}
141
142static inline void hfa384x_outw_debug(struct net_device *dev, int a, u16 v)
143{
144 struct hostap_interface *iface;
145 local_info_t *local;
146 unsigned long flags;
147
148 iface = netdev_priv(dev);
149 local = iface->local;
150
151 spin_lock_irqsave(&local->lock, flags);
152 prism2_io_debug_add(dev, PRISM2_IO_DEBUG_CMD_OUTW, a, v);
153 outw(v, dev->base_addr + a);
154 spin_unlock_irqrestore(&local->lock, flags);
155}
156
157static inline u16 hfa384x_inw_debug(struct net_device *dev, int a)
158{
159 struct hostap_interface *iface;
160 local_info_t *local;
161 unsigned long flags;
162 u16 v;
163
164 iface = netdev_priv(dev);
165 local = iface->local;
166
167 spin_lock_irqsave(&local->lock, flags);
168 v = inw(dev->base_addr + a);
169 prism2_io_debug_add(dev, PRISM2_IO_DEBUG_CMD_INW, a, v);
170 spin_unlock_irqrestore(&local->lock, flags);
171 return v;
172}
173
174static inline void hfa384x_outsw_debug(struct net_device *dev, int a,
175 u8 *buf, int wc)
176{
177 struct hostap_interface *iface;
178 local_info_t *local;
179 unsigned long flags;
180
181 iface = netdev_priv(dev);
182 local = iface->local;
183
184 spin_lock_irqsave(&local->lock, flags);
185 prism2_io_debug_add(dev, PRISM2_IO_DEBUG_CMD_OUTSW, a, wc);
186 outsw(dev->base_addr + a, buf, wc);
187 spin_unlock_irqrestore(&local->lock, flags);
188}
189
190static inline void hfa384x_insw_debug(struct net_device *dev, int a,
191 u8 *buf, int wc)
192{
193 struct hostap_interface *iface;
194 local_info_t *local;
195 unsigned long flags;
196
197 iface = netdev_priv(dev);
198 local = iface->local;
199
200 spin_lock_irqsave(&local->lock, flags);
201 prism2_io_debug_add(dev, PRISM2_IO_DEBUG_CMD_INSW, a, wc);
202 insw(dev->base_addr + a, buf, wc);
203 spin_unlock_irqrestore(&local->lock, flags);
204}
205
206#define HFA384X_OUTB(v,a) hfa384x_outb_debug(dev, (a), (v))
207#define HFA384X_INB(a) hfa384x_inb_debug(dev, (a))
208#define HFA384X_OUTW(v,a) hfa384x_outw_debug(dev, (a), (v))
209#define HFA384X_INW(a) hfa384x_inw_debug(dev, (a))
210#define HFA384X_OUTSW(a, buf, wc) hfa384x_outsw_debug(dev, (a), (buf), (wc))
211#define HFA384X_INSW(a, buf, wc) hfa384x_insw_debug(dev, (a), (buf), (wc))
212
213#else /* PRISM2_IO_DEBUG */
214
215#define HFA384X_OUTB(v,a) outb((v), dev->base_addr + (a))
216#define HFA384X_INB(a) inb(dev->base_addr + (a))
217#define HFA384X_OUTW(v,a) outw((v), dev->base_addr + (a))
218#define HFA384X_INW(a) inw(dev->base_addr + (a))
219#define HFA384X_INSW(a, buf, wc) insw(dev->base_addr + (a), buf, wc)
220#define HFA384X_OUTSW(a, buf, wc) outsw(dev->base_addr + (a), buf, wc)
221
222#endif /* PRISM2_IO_DEBUG */
223
224
225static int hfa384x_from_bap(struct net_device *dev, u16 bap, void *buf,
226 int len)
227{
228 u16 d_off;
229 u16 *pos;
230
231 d_off = (bap == 1) ? HFA384X_DATA1_OFF : HFA384X_DATA0_OFF;
232 pos = (u16 *) buf;
233
234 if (len / 2)
235 HFA384X_INSW(d_off, buf, len / 2);
236 pos += len / 2;
237
238 if (len & 1)
239 *((char *) pos) = HFA384X_INB(d_off);
240
241 return 0;
242}
243
244
245static int hfa384x_to_bap(struct net_device *dev, u16 bap, void *buf, int len)
246{
247 u16 d_off;
248 u16 *pos;
249
250 d_off = (bap == 1) ? HFA384X_DATA1_OFF : HFA384X_DATA0_OFF;
251 pos = (u16 *) buf;
252
253 if (len / 2)
254 HFA384X_OUTSW(d_off, buf, len / 2);
255 pos += len / 2;
256
257 if (len & 1)
258 HFA384X_OUTB(*((char *) pos), d_off);
259
260 return 0;
261}
262
263
264/* FIX: This might change at some point.. */
265#include "hostap_hw.c"
266
267
268static void prism2_plx_cor_sreset(local_info_t *local)
269{
270 unsigned char corsave;
271 struct hostap_plx_priv *hw_priv = local->hw_priv;
272
273 printk(KERN_DEBUG "%s: Doing reset via direct COR access.\n",
274 dev_info);
275
276 /* Set sreset bit of COR and clear it after hold time */
277
278 if (hw_priv->attr_mem == NULL) {
279 /* TMD7160 - COR at card's first I/O addr */
280 corsave = inb(hw_priv->cor_offset);
281 outb(corsave | COR_SRESET, hw_priv->cor_offset);
282 mdelay(2);
283 outb(corsave & ~COR_SRESET, hw_priv->cor_offset);
284 mdelay(2);
285 } else {
286 /* PLX9052 */
287 corsave = readb(hw_priv->attr_mem + hw_priv->cor_offset);
288 writeb(corsave | COR_SRESET,
289 hw_priv->attr_mem + hw_priv->cor_offset);
290 mdelay(2);
291 writeb(corsave & ~COR_SRESET,
292 hw_priv->attr_mem + hw_priv->cor_offset);
293 mdelay(2);
294 }
295}
296
297
298static void prism2_plx_genesis_reset(local_info_t *local, int hcr)
299{
300 unsigned char corsave;
301 struct hostap_plx_priv *hw_priv = local->hw_priv;
302
303 if (hw_priv->attr_mem == NULL) {
304 /* TMD7160 - COR at card's first I/O addr */
305 corsave = inb(hw_priv->cor_offset);
306 outb(corsave | COR_SRESET, hw_priv->cor_offset);
307 mdelay(10);
308 outb(hcr, hw_priv->cor_offset + 2);
309 mdelay(10);
310 outb(corsave & ~COR_SRESET, hw_priv->cor_offset);
311 mdelay(10);
312 } else {
313 /* PLX9052 */
314 corsave = readb(hw_priv->attr_mem + hw_priv->cor_offset);
315 writeb(corsave | COR_SRESET,
316 hw_priv->attr_mem + hw_priv->cor_offset);
317 mdelay(10);
318 writeb(hcr, hw_priv->attr_mem + hw_priv->cor_offset + 2);
319 mdelay(10);
320 writeb(corsave & ~COR_SRESET,
321 hw_priv->attr_mem + hw_priv->cor_offset);
322 mdelay(10);
323 }
324}
325
326
327static struct prism2_helper_functions prism2_plx_funcs =
328{
329 .card_present = NULL,
330 .cor_sreset = prism2_plx_cor_sreset,
331 .dev_open = NULL,
332 .dev_close = NULL,
333 .genesis_reset = prism2_plx_genesis_reset,
334 .hw_type = HOSTAP_HW_PLX,
335};
336
337
338static int prism2_plx_check_cis(void __iomem *attr_mem, int attr_len,
339 unsigned int *cor_offset,
340 unsigned int *cor_index)
341{
342#define CISTPL_CONFIG 0x1A
343#define CISTPL_MANFID 0x20
344#define CISTPL_END 0xFF
345#define CIS_MAX_LEN 256
346 u8 *cis;
347 int i, pos;
348 unsigned int rmsz, rasz, manfid1, manfid2;
349 struct prism2_plx_manfid *manfid;
350
351 cis = kmalloc(CIS_MAX_LEN, GFP_KERNEL);
352 if (cis == NULL)
353 return -ENOMEM;
354
355 /* read CIS; it is in even offsets in the beginning of attr_mem */
356 for (i = 0; i < CIS_MAX_LEN; i++)
357 cis[i] = readb(attr_mem + 2 * i);
358 printk(KERN_DEBUG "%s: CIS: %02x %02x %02x %02x %02x %02x ...\n",
359 dev_info, cis[0], cis[1], cis[2], cis[3], cis[4], cis[5]);
360
361 /* set reasonable defaults for Prism2 cards just in case CIS parsing
362 * fails */
363 *cor_offset = 0x3e0;
364 *cor_index = 0x01;
365 manfid1 = manfid2 = 0;
366
367 pos = 0;
368 while (pos < CIS_MAX_LEN - 1 && cis[pos] != CISTPL_END) {
369 if (pos + cis[pos + 1] >= CIS_MAX_LEN)
370 goto cis_error;
371
372 switch (cis[pos]) {
373 case CISTPL_CONFIG:
374 if (cis[pos + 1] < 1)
375 goto cis_error;
376 rmsz = (cis[pos + 2] & 0x3c) >> 2;
377 rasz = cis[pos + 2] & 0x03;
378 if (4 + rasz + rmsz > cis[pos + 1])
379 goto cis_error;
380 *cor_index = cis[pos + 3] & 0x3F;
381 *cor_offset = 0;
382 for (i = 0; i <= rasz; i++)
383 *cor_offset += cis[pos + 4 + i] << (8 * i);
384 printk(KERN_DEBUG "%s: cor_index=0x%x "
385 "cor_offset=0x%x\n", dev_info,
386 *cor_index, *cor_offset);
387 if (*cor_offset > attr_len) {
388 printk(KERN_ERR "%s: COR offset not within "
389 "attr_mem\n", dev_info);
390 kfree(cis);
391 return -1;
392 }
393 break;
394
395 case CISTPL_MANFID:
396 if (cis[pos + 1] < 4)
397 goto cis_error;
398 manfid1 = cis[pos + 2] + (cis[pos + 3] << 8);
399 manfid2 = cis[pos + 4] + (cis[pos + 5] << 8);
400 printk(KERN_DEBUG "%s: manfid=0x%04x, 0x%04x\n",
401 dev_info, manfid1, manfid2);
402 break;
403 }
404
405 pos += cis[pos + 1] + 2;
406 }
407
408 if (pos >= CIS_MAX_LEN || cis[pos] != CISTPL_END)
409 goto cis_error;
410
411 for (manfid = prism2_plx_known_manfids; manfid->manfid1 != 0; manfid++)
412 if (manfid1 == manfid->manfid1 && manfid2 == manfid->manfid2) {
413 kfree(cis);
414 return 0;
415 }
416
417 printk(KERN_INFO "%s: unknown manfid 0x%04x, 0x%04x - assuming this is"
418 " not supported card\n", dev_info, manfid1, manfid2);
419 goto fail;
420
421 cis_error:
422 printk(KERN_WARNING "%s: invalid CIS data\n", dev_info);
423
424 fail:
425 kfree(cis);
426 if (ignore_cis) {
427 printk(KERN_INFO "%s: ignore_cis parameter set - ignoring "
428 "errors during CIS verification\n", dev_info);
429 return 0;
430 }
431 return -1;
432}
433
434
435static int prism2_plx_probe(struct pci_dev *pdev,
436 const struct pci_device_id *id)
437{
438 unsigned int pccard_ioaddr, plx_ioaddr;
439 unsigned long pccard_attr_mem;
440 unsigned int pccard_attr_len;
441 void __iomem *attr_mem = NULL;
442 unsigned int cor_offset, cor_index;
443 u32 reg;
444 local_info_t *local = NULL;
445 struct net_device *dev = NULL;
446 struct hostap_interface *iface;
447 static int cards_found /* = 0 */;
448 int irq_registered = 0;
449 int tmd7160;
450 struct hostap_plx_priv *hw_priv;
451
452 hw_priv = kmalloc(sizeof(*hw_priv), GFP_KERNEL);
453 if (hw_priv == NULL)
454 return -ENOMEM;
455 memset(hw_priv, 0, sizeof(*hw_priv));
456
457 if (pci_enable_device(pdev))
458 return -EIO;
459
460 /* National Datacomm NCP130 based on TMD7160, not PLX9052. */
461 tmd7160 = (pdev->vendor == 0x15e8) && (pdev->device == 0x0131);
462
463 plx_ioaddr = pci_resource_start(pdev, 1);
464 pccard_ioaddr = pci_resource_start(pdev, tmd7160 ? 2 : 3);
465
466 if (tmd7160) {
467 /* TMD7160 */
468 attr_mem = NULL; /* no access to PC Card attribute memory */
469
470 printk(KERN_INFO "TMD7160 PCI/PCMCIA adapter: io=0x%x, "
471 "irq=%d, pccard_io=0x%x\n",
472 plx_ioaddr, pdev->irq, pccard_ioaddr);
473
474 cor_offset = plx_ioaddr;
475 cor_index = 0x04;
476
477 outb(cor_index | COR_LEVLREQ | COR_ENABLE_FUNC, plx_ioaddr);
478 mdelay(1);
479 reg = inb(plx_ioaddr);
480 if (reg != (cor_index | COR_LEVLREQ | COR_ENABLE_FUNC)) {
481 printk(KERN_ERR "%s: Error setting COR (expected="
482 "0x%02x, was=0x%02x)\n", dev_info,
483 cor_index | COR_LEVLREQ | COR_ENABLE_FUNC, reg);
484 goto fail;
485 }
486 } else {
487 /* PLX9052 */
488 pccard_attr_mem = pci_resource_start(pdev, 2);
489 pccard_attr_len = pci_resource_len(pdev, 2);
490 if (pccard_attr_len < PLX_MIN_ATTR_LEN)
491 goto fail;
492
493
494 attr_mem = ioremap(pccard_attr_mem, pccard_attr_len);
495 if (attr_mem == NULL) {
496 printk(KERN_ERR "%s: cannot remap attr_mem\n",
497 dev_info);
498 goto fail;
499 }
500
501 printk(KERN_INFO "PLX9052 PCI/PCMCIA adapter: "
502 "mem=0x%lx, plx_io=0x%x, irq=%d, pccard_io=0x%x\n",
503 pccard_attr_mem, plx_ioaddr, pdev->irq, pccard_ioaddr);
504
505 if (prism2_plx_check_cis(attr_mem, pccard_attr_len,
506 &cor_offset, &cor_index)) {
507 printk(KERN_INFO "Unknown PC Card CIS - not a "
508 "Prism2/2.5 card?\n");
509 goto fail;
510 }
511
512 printk(KERN_DEBUG "Prism2/2.5 PC Card detected in PLX9052 "
513 "adapter\n");
514
515 /* Write COR to enable PC Card */
516 writeb(cor_index | COR_LEVLREQ | COR_ENABLE_FUNC,
517 attr_mem + cor_offset);
518
519 /* Enable PCI interrupts if they are not already enabled */
520 reg = inl(plx_ioaddr + PLX_INTCSR);
521 printk(KERN_DEBUG "PLX_INTCSR=0x%x\n", reg);
522 if (!(reg & PLX_INTCSR_PCI_INTEN)) {
523 outl(reg | PLX_INTCSR_PCI_INTEN,
524 plx_ioaddr + PLX_INTCSR);
525 if (!(inl(plx_ioaddr + PLX_INTCSR) &
526 PLX_INTCSR_PCI_INTEN)) {
527 printk(KERN_WARNING "%s: Could not enable "
528 "Local Interrupts\n", dev_info);
529 goto fail;
530 }
531 }
532
533 reg = inl(plx_ioaddr + PLX_CNTRL);
534 printk(KERN_DEBUG "PLX_CNTRL=0x%x (Serial EEPROM "
535 "present=%d)\n",
536 reg, (reg & PLX_CNTRL_SERIAL_EEPROM_PRESENT) != 0);
537 /* should set PLX_PCIIPR to 0x01 (INTA#) if Serial EEPROM is
538 * not present; but are there really such cards in use(?) */
539 }
540
541 dev = prism2_init_local_data(&prism2_plx_funcs, cards_found,
542 &pdev->dev);
543 if (dev == NULL)
544 goto fail;
545 iface = netdev_priv(dev);
546 local = iface->local;
547 local->hw_priv = hw_priv;
548 cards_found++;
549
550 dev->irq = pdev->irq;
551 dev->base_addr = pccard_ioaddr;
552 hw_priv->attr_mem = attr_mem;
553 hw_priv->cor_offset = cor_offset;
554
555 pci_set_drvdata(pdev, dev);
556
557 if (request_irq(dev->irq, prism2_interrupt, SA_SHIRQ, dev->name,
558 dev)) {
559 printk(KERN_WARNING "%s: request_irq failed\n", dev->name);
560 goto fail;
561 } else
562 irq_registered = 1;
563
564 if (prism2_hw_config(dev, 1)) {
565 printk(KERN_DEBUG "%s: hardware initialization failed\n",
566 dev_info);
567 goto fail;
568 }
569
570 return hostap_hw_ready(dev);
571
572 fail:
573 kfree(hw_priv);
574 if (local)
575 local->hw_priv = NULL;
576 prism2_free_local_data(dev);
577
578 if (irq_registered && dev)
579 free_irq(dev->irq, dev);
580
581 if (attr_mem)
582 iounmap(attr_mem);
583
584 pci_disable_device(pdev);
585
586 return -ENODEV;
587}
588
589
590static void prism2_plx_remove(struct pci_dev *pdev)
591{
592 struct net_device *dev;
593 struct hostap_interface *iface;
594 struct hostap_plx_priv *hw_priv;
595
596 dev = pci_get_drvdata(pdev);
597 iface = netdev_priv(dev);
598 hw_priv = iface->local->hw_priv;
599
600 /* Reset the hardware, and ensure interrupts are disabled. */
601 prism2_plx_cor_sreset(iface->local);
602 hfa384x_disable_interrupts(dev);
603
604 if (hw_priv->attr_mem)
605 iounmap(hw_priv->attr_mem);
606 if (dev->irq)
607 free_irq(dev->irq, dev);
608
609 kfree(iface->local->hw_priv);
610 iface->local->hw_priv = NULL;
611 prism2_free_local_data(dev);
612 pci_disable_device(pdev);
613}
614
615
616MODULE_DEVICE_TABLE(pci, prism2_plx_id_table);
617
618static struct pci_driver prism2_plx_drv_id = {
619 .name = "prism2_plx",
620 .id_table = prism2_plx_id_table,
621 .probe = prism2_plx_probe,
622 .remove = prism2_plx_remove,
623 .suspend = NULL,
624 .resume = NULL,
625 .enable_wake = NULL
626};
627
628
629static int __init init_prism2_plx(void)
630{
631 printk(KERN_INFO "%s: %s\n", dev_info, version);
632
633 return pci_register_driver(&prism2_plx_drv_id);
634}
635
636
637static void __exit exit_prism2_plx(void)
638{
639 pci_unregister_driver(&prism2_plx_drv_id);
640 printk(KERN_INFO "%s: Driver unloaded\n", dev_info);
641}
642
643
644module_init(init_prism2_plx);
645module_exit(exit_prism2_plx);
diff --git a/drivers/net/wireless/hostap/hostap_proc.c b/drivers/net/wireless/hostap/hostap_proc.c
new file mode 100644
index 000000000000..a0a4cbd4937a
--- /dev/null
+++ b/drivers/net/wireless/hostap/hostap_proc.c
@@ -0,0 +1,448 @@
1/* /proc routines for Host AP driver */
2
3#define PROC_LIMIT (PAGE_SIZE - 80)
4
5
6#ifndef PRISM2_NO_PROCFS_DEBUG
7static int prism2_debug_proc_read(char *page, char **start, off_t off,
8 int count, int *eof, void *data)
9{
10 char *p = page;
11 local_info_t *local = (local_info_t *) data;
12 int i;
13
14 if (off != 0) {
15 *eof = 1;
16 return 0;
17 }
18
19 p += sprintf(p, "next_txfid=%d next_alloc=%d\n",
20 local->next_txfid, local->next_alloc);
21 for (i = 0; i < PRISM2_TXFID_COUNT; i++)
22 p += sprintf(p, "FID: tx=%04X intransmit=%04X\n",
23 local->txfid[i], local->intransmitfid[i]);
24 p += sprintf(p, "FW TX rate control: %d\n", local->fw_tx_rate_control);
25 p += sprintf(p, "beacon_int=%d\n", local->beacon_int);
26 p += sprintf(p, "dtim_period=%d\n", local->dtim_period);
27 p += sprintf(p, "wds_max_connections=%d\n",
28 local->wds_max_connections);
29 p += sprintf(p, "dev_enabled=%d\n", local->dev_enabled);
30 p += sprintf(p, "sw_tick_stuck=%d\n", local->sw_tick_stuck);
31 for (i = 0; i < WEP_KEYS; i++) {
32 if (local->crypt[i] && local->crypt[i]->ops) {
33 p += sprintf(p, "crypt[%d]=%s\n",
34 i, local->crypt[i]->ops->name);
35 }
36 }
37 p += sprintf(p, "pri_only=%d\n", local->pri_only);
38 p += sprintf(p, "pci=%d\n", local->func->hw_type == HOSTAP_HW_PCI);
39 p += sprintf(p, "sram_type=%d\n", local->sram_type);
40 p += sprintf(p, "no_pri=%d\n", local->no_pri);
41
42 return (p - page);
43}
44#endif /* PRISM2_NO_PROCFS_DEBUG */
45
46
47static int prism2_stats_proc_read(char *page, char **start, off_t off,
48 int count, int *eof, void *data)
49{
50 char *p = page;
51 local_info_t *local = (local_info_t *) data;
52 struct comm_tallies_sums *sums = (struct comm_tallies_sums *)
53 &local->comm_tallies;
54
55 if (off != 0) {
56 *eof = 1;
57 return 0;
58 }
59
60 p += sprintf(p, "TxUnicastFrames=%u\n", sums->tx_unicast_frames);
61 p += sprintf(p, "TxMulticastframes=%u\n", sums->tx_multicast_frames);
62 p += sprintf(p, "TxFragments=%u\n", sums->tx_fragments);
63 p += sprintf(p, "TxUnicastOctets=%u\n", sums->tx_unicast_octets);
64 p += sprintf(p, "TxMulticastOctets=%u\n", sums->tx_multicast_octets);
65 p += sprintf(p, "TxDeferredTransmissions=%u\n",
66 sums->tx_deferred_transmissions);
67 p += sprintf(p, "TxSingleRetryFrames=%u\n",
68 sums->tx_single_retry_frames);
69 p += sprintf(p, "TxMultipleRetryFrames=%u\n",
70 sums->tx_multiple_retry_frames);
71 p += sprintf(p, "TxRetryLimitExceeded=%u\n",
72 sums->tx_retry_limit_exceeded);
73 p += sprintf(p, "TxDiscards=%u\n", sums->tx_discards);
74 p += sprintf(p, "RxUnicastFrames=%u\n", sums->rx_unicast_frames);
75 p += sprintf(p, "RxMulticastFrames=%u\n", sums->rx_multicast_frames);
76 p += sprintf(p, "RxFragments=%u\n", sums->rx_fragments);
77 p += sprintf(p, "RxUnicastOctets=%u\n", sums->rx_unicast_octets);
78 p += sprintf(p, "RxMulticastOctets=%u\n", sums->rx_multicast_octets);
79 p += sprintf(p, "RxFCSErrors=%u\n", sums->rx_fcs_errors);
80 p += sprintf(p, "RxDiscardsNoBuffer=%u\n",
81 sums->rx_discards_no_buffer);
82 p += sprintf(p, "TxDiscardsWrongSA=%u\n", sums->tx_discards_wrong_sa);
83 p += sprintf(p, "RxDiscardsWEPUndecryptable=%u\n",
84 sums->rx_discards_wep_undecryptable);
85 p += sprintf(p, "RxMessageInMsgFragments=%u\n",
86 sums->rx_message_in_msg_fragments);
87 p += sprintf(p, "RxMessageInBadMsgFragments=%u\n",
88 sums->rx_message_in_bad_msg_fragments);
89 /* FIX: this may grow too long for one page(?) */
90
91 return (p - page);
92}
93
94
95static int prism2_wds_proc_read(char *page, char **start, off_t off,
96 int count, int *eof, void *data)
97{
98 char *p = page;
99 local_info_t *local = (local_info_t *) data;
100 struct list_head *ptr;
101 struct hostap_interface *iface;
102
103 if (off > PROC_LIMIT) {
104 *eof = 1;
105 return 0;
106 }
107
108 read_lock_bh(&local->iface_lock);
109 list_for_each(ptr, &local->hostap_interfaces) {
110 iface = list_entry(ptr, struct hostap_interface, list);
111 if (iface->type != HOSTAP_INTERFACE_WDS)
112 continue;
113 p += sprintf(p, "%s\t" MACSTR "\n",
114 iface->dev->name,
115 MAC2STR(iface->u.wds.remote_addr));
116 if ((p - page) > PROC_LIMIT) {
117 printk(KERN_DEBUG "%s: wds proc did not fit\n",
118 local->dev->name);
119 break;
120 }
121 }
122 read_unlock_bh(&local->iface_lock);
123
124 if ((p - page) <= off) {
125 *eof = 1;
126 return 0;
127 }
128
129 *start = page + off;
130
131 return (p - page - off);
132}
133
134
135static int prism2_bss_list_proc_read(char *page, char **start, off_t off,
136 int count, int *eof, void *data)
137{
138 char *p = page;
139 local_info_t *local = (local_info_t *) data;
140 struct list_head *ptr;
141 struct hostap_bss_info *bss;
142 int i;
143
144 if (off > PROC_LIMIT) {
145 *eof = 1;
146 return 0;
147 }
148
149 p += sprintf(p, "#BSSID\tlast_update\tcount\tcapab_info\tSSID(txt)\t"
150 "SSID(hex)\tWPA IE\n");
151 spin_lock_bh(&local->lock);
152 list_for_each(ptr, &local->bss_list) {
153 bss = list_entry(ptr, struct hostap_bss_info, list);
154 p += sprintf(p, MACSTR "\t%lu\t%u\t0x%x\t",
155 MAC2STR(bss->bssid), bss->last_update,
156 bss->count, bss->capab_info);
157 for (i = 0; i < bss->ssid_len; i++) {
158 p += sprintf(p, "%c",
159 bss->ssid[i] >= 32 && bss->ssid[i] < 127 ?
160 bss->ssid[i] : '_');
161 }
162 p += sprintf(p, "\t");
163 for (i = 0; i < bss->ssid_len; i++) {
164 p += sprintf(p, "%02x", bss->ssid[i]);
165 }
166 p += sprintf(p, "\t");
167 for (i = 0; i < bss->wpa_ie_len; i++) {
168 p += sprintf(p, "%02x", bss->wpa_ie[i]);
169 }
170 p += sprintf(p, "\n");
171 if ((p - page) > PROC_LIMIT) {
172 printk(KERN_DEBUG "%s: BSS proc did not fit\n",
173 local->dev->name);
174 break;
175 }
176 }
177 spin_unlock_bh(&local->lock);
178
179 if ((p - page) <= off) {
180 *eof = 1;
181 return 0;
182 }
183
184 *start = page + off;
185
186 return (p - page - off);
187}
188
189
190static int prism2_crypt_proc_read(char *page, char **start, off_t off,
191 int count, int *eof, void *data)
192{
193 char *p = page;
194 local_info_t *local = (local_info_t *) data;
195 int i;
196
197 if (off > PROC_LIMIT) {
198 *eof = 1;
199 return 0;
200 }
201
202 p += sprintf(p, "tx_keyidx=%d\n", local->tx_keyidx);
203 for (i = 0; i < WEP_KEYS; i++) {
204 if (local->crypt[i] && local->crypt[i]->ops &&
205 local->crypt[i]->ops->print_stats) {
206 p = local->crypt[i]->ops->print_stats(
207 p, local->crypt[i]->priv);
208 }
209 }
210
211 if ((p - page) <= off) {
212 *eof = 1;
213 return 0;
214 }
215
216 *start = page + off;
217
218 return (p - page - off);
219}
220
221
222static int prism2_pda_proc_read(char *page, char **start, off_t off,
223 int count, int *eof, void *data)
224{
225 local_info_t *local = (local_info_t *) data;
226
227 if (local->pda == NULL || off >= PRISM2_PDA_SIZE) {
228 *eof = 1;
229 return 0;
230 }
231
232 if (off + count > PRISM2_PDA_SIZE)
233 count = PRISM2_PDA_SIZE - off;
234
235 memcpy(page, local->pda + off, count);
236 return count;
237}
238
239
240static int prism2_aux_dump_proc_read(char *page, char **start, off_t off,
241 int count, int *eof, void *data)
242{
243 local_info_t *local = (local_info_t *) data;
244
245 if (local->func->read_aux == NULL) {
246 *eof = 1;
247 return 0;
248 }
249
250 if (local->func->read_aux(local->dev, off, count, page)) {
251 *eof = 1;
252 return 0;
253 }
254 *start = page;
255
256 return count;
257}
258
259
260#ifdef PRISM2_IO_DEBUG
261static int prism2_io_debug_proc_read(char *page, char **start, off_t off,
262 int count, int *eof, void *data)
263{
264 local_info_t *local = (local_info_t *) data;
265 int head = local->io_debug_head;
266 int start_bytes, left, copy, copied;
267
268 if (off + count > PRISM2_IO_DEBUG_SIZE * 4) {
269 *eof = 1;
270 if (off >= PRISM2_IO_DEBUG_SIZE * 4)
271 return 0;
272 count = PRISM2_IO_DEBUG_SIZE * 4 - off;
273 }
274
275 copied = 0;
276 start_bytes = (PRISM2_IO_DEBUG_SIZE - head) * 4;
277 left = count;
278
279 if (off < start_bytes) {
280 copy = start_bytes - off;
281 if (copy > count)
282 copy = count;
283 memcpy(page, ((u8 *) &local->io_debug[head]) + off, copy);
284 left -= copy;
285 if (left > 0)
286 memcpy(&page[copy], local->io_debug, left);
287 } else {
288 memcpy(page, ((u8 *) local->io_debug) + (off - start_bytes),
289 left);
290 }
291
292 *start = page;
293
294 return count;
295}
296#endif /* PRISM2_IO_DEBUG */
297
298
299#ifndef PRISM2_NO_STATION_MODES
300static int prism2_scan_results_proc_read(char *page, char **start, off_t off,
301 int count, int *eof, void *data)
302{
303 char *p = page;
304 local_info_t *local = (local_info_t *) data;
305 int entry, i, len, total = 0;
306 struct hfa384x_hostscan_result *scanres;
307 u8 *pos;
308
309 p += sprintf(p, "CHID ANL SL BcnInt Capab Rate BSSID ATIM SupRates "
310 "SSID\n");
311
312 spin_lock_bh(&local->lock);
313 for (entry = 0; entry < local->last_scan_results_count; entry++) {
314 scanres = &local->last_scan_results[entry];
315
316 if (total + (p - page) <= off) {
317 total += p - page;
318 p = page;
319 }
320 if (total + (p - page) > off + count)
321 break;
322 if ((p - page) > (PAGE_SIZE - 200))
323 break;
324
325 p += sprintf(p, "%d %d %d %d 0x%02x %d " MACSTR " %d ",
326 le16_to_cpu(scanres->chid),
327 (s16) le16_to_cpu(scanres->anl),
328 (s16) le16_to_cpu(scanres->sl),
329 le16_to_cpu(scanres->beacon_interval),
330 le16_to_cpu(scanres->capability),
331 le16_to_cpu(scanres->rate),
332 MAC2STR(scanres->bssid),
333 le16_to_cpu(scanres->atim));
334
335 pos = scanres->sup_rates;
336 for (i = 0; i < sizeof(scanres->sup_rates); i++) {
337 if (pos[i] == 0)
338 break;
339 p += sprintf(p, "<%02x>", pos[i]);
340 }
341 p += sprintf(p, " ");
342
343 pos = scanres->ssid;
344 len = le16_to_cpu(scanres->ssid_len);
345 if (len > 32)
346 len = 32;
347 for (i = 0; i < len; i++) {
348 unsigned char c = pos[i];
349 if (c >= 32 && c < 127)
350 p += sprintf(p, "%c", c);
351 else
352 p += sprintf(p, "<%02x>", c);
353 }
354 p += sprintf(p, "\n");
355 }
356 spin_unlock_bh(&local->lock);
357
358 total += (p - page);
359 if (total >= off + count)
360 *eof = 1;
361
362 if (total < off) {
363 *eof = 1;
364 return 0;
365 }
366
367 len = total - off;
368 if (len > (p - page))
369 len = p - page;
370 *start = p - len;
371 if (len > count)
372 len = count;
373
374 return len;
375}
376#endif /* PRISM2_NO_STATION_MODES */
377
378
379void hostap_init_proc(local_info_t *local)
380{
381 local->proc = NULL;
382
383 if (hostap_proc == NULL) {
384 printk(KERN_WARNING "%s: hostap proc directory not created\n",
385 local->dev->name);
386 return;
387 }
388
389 local->proc = proc_mkdir(local->ddev->name, hostap_proc);
390 if (local->proc == NULL) {
391 printk(KERN_INFO "/proc/net/hostap/%s creation failed\n",
392 local->ddev->name);
393 return;
394 }
395
396#ifndef PRISM2_NO_PROCFS_DEBUG
397 create_proc_read_entry("debug", 0, local->proc,
398 prism2_debug_proc_read, local);
399#endif /* PRISM2_NO_PROCFS_DEBUG */
400 create_proc_read_entry("stats", 0, local->proc,
401 prism2_stats_proc_read, local);
402 create_proc_read_entry("wds", 0, local->proc,
403 prism2_wds_proc_read, local);
404 create_proc_read_entry("pda", 0, local->proc,
405 prism2_pda_proc_read, local);
406 create_proc_read_entry("aux_dump", 0, local->proc,
407 prism2_aux_dump_proc_read, local);
408 create_proc_read_entry("bss_list", 0, local->proc,
409 prism2_bss_list_proc_read, local);
410 create_proc_read_entry("crypt", 0, local->proc,
411 prism2_crypt_proc_read, local);
412#ifdef PRISM2_IO_DEBUG
413 create_proc_read_entry("io_debug", 0, local->proc,
414 prism2_io_debug_proc_read, local);
415#endif /* PRISM2_IO_DEBUG */
416#ifndef PRISM2_NO_STATION_MODES
417 create_proc_read_entry("scan_results", 0, local->proc,
418 prism2_scan_results_proc_read, local);
419#endif /* PRISM2_NO_STATION_MODES */
420}
421
422
423void hostap_remove_proc(local_info_t *local)
424{
425 if (local->proc != NULL) {
426#ifndef PRISM2_NO_STATION_MODES
427 remove_proc_entry("scan_results", local->proc);
428#endif /* PRISM2_NO_STATION_MODES */
429#ifdef PRISM2_IO_DEBUG
430 remove_proc_entry("io_debug", local->proc);
431#endif /* PRISM2_IO_DEBUG */
432 remove_proc_entry("pda", local->proc);
433 remove_proc_entry("aux_dump", local->proc);
434 remove_proc_entry("wds", local->proc);
435 remove_proc_entry("stats", local->proc);
436 remove_proc_entry("bss_list", local->proc);
437 remove_proc_entry("crypt", local->proc);
438#ifndef PRISM2_NO_PROCFS_DEBUG
439 remove_proc_entry("debug", local->proc);
440#endif /* PRISM2_NO_PROCFS_DEBUG */
441 if (hostap_proc != NULL)
442 remove_proc_entry(local->proc->name, hostap_proc);
443 }
444}
445
446
447EXPORT_SYMBOL(hostap_init_proc);
448EXPORT_SYMBOL(hostap_remove_proc);
diff --git a/drivers/net/wireless/hostap/hostap_wlan.h b/drivers/net/wireless/hostap/hostap_wlan.h
new file mode 100644
index 000000000000..cc061e1560d3
--- /dev/null
+++ b/drivers/net/wireless/hostap/hostap_wlan.h
@@ -0,0 +1,1033 @@
1#ifndef HOSTAP_WLAN_H
2#define HOSTAP_WLAN_H
3
4#include "hostap_config.h"
5#include "hostap_common.h"
6
7#define MAX_PARM_DEVICES 8
8#define PARM_MIN_MAX "1-" __MODULE_STRING(MAX_PARM_DEVICES)
9#define DEF_INTS -1, -1, -1, -1, -1, -1, -1
10#define GET_INT_PARM(var,idx) var[var[idx] < 0 ? 0 : idx]
11
12
13/* Specific skb->protocol value that indicates that the packet already contains
14 * txdesc header.
15 * FIX: This might need own value that would be allocated especially for Prism2
16 * txdesc; ETH_P_CONTROL is commented as "Card specific control frames".
17 * However, these skb's should have only minimal path in the kernel side since
18 * prism2_send_mgmt() sends these with dev_queue_xmit() to prism2_tx(). */
19#define ETH_P_HOSTAP ETH_P_CONTROL
20
21/* ARPHRD_IEEE80211_PRISM uses a bloated version of Prism2 RX frame header
22 * (from linux-wlan-ng) */
23struct linux_wlan_ng_val {
24 u32 did;
25 u16 status, len;
26 u32 data;
27} __attribute__ ((packed));
28
29struct linux_wlan_ng_prism_hdr {
30 u32 msgcode, msglen;
31 char devname[16];
32 struct linux_wlan_ng_val hosttime, mactime, channel, rssi, sq, signal,
33 noise, rate, istx, frmlen;
34} __attribute__ ((packed));
35
36struct linux_wlan_ng_cap_hdr {
37 u32 version;
38 u32 length;
39 u64 mactime;
40 u64 hosttime;
41 u32 phytype;
42 u32 channel;
43 u32 datarate;
44 u32 antenna;
45 u32 priority;
46 u32 ssi_type;
47 s32 ssi_signal;
48 s32 ssi_noise;
49 u32 preamble;
50 u32 encoding;
51} __attribute__ ((packed));
52
53#define LWNG_CAP_DID_BASE (4 | (1 << 6)) /* section 4, group 1 */
54#define LWNG_CAPHDR_VERSION 0x80211001
55
56struct hfa384x_rx_frame {
57 /* HFA384X RX frame descriptor */
58 u16 status; /* HFA384X_RX_STATUS_ flags */
59 u32 time; /* timestamp, 1 microsecond resolution */
60 u8 silence; /* 27 .. 154; seems to be 0 */
61 u8 signal; /* 27 .. 154 */
62 u8 rate; /* 10, 20, 55, or 110 */
63 u8 rxflow;
64 u32 reserved;
65
66 /* 802.11 */
67 u16 frame_control;
68 u16 duration_id;
69 u8 addr1[6];
70 u8 addr2[6];
71 u8 addr3[6];
72 u16 seq_ctrl;
73 u8 addr4[6];
74 u16 data_len;
75
76 /* 802.3 */
77 u8 dst_addr[6];
78 u8 src_addr[6];
79 u16 len;
80
81 /* followed by frame data; max 2304 bytes */
82} __attribute__ ((packed));
83
84
85struct hfa384x_tx_frame {
86 /* HFA384X TX frame descriptor */
87 u16 status; /* HFA384X_TX_STATUS_ flags */
88 u16 reserved1;
89 u16 reserved2;
90 u32 sw_support;
91 u8 retry_count; /* not yet implemented */
92 u8 tx_rate; /* Host AP only; 0 = firmware, or 10, 20, 55, 110 */
93 u16 tx_control; /* HFA384X_TX_CTRL_ flags */
94
95 /* 802.11 */
96 u16 frame_control; /* parts not used */
97 u16 duration_id;
98 u8 addr1[6];
99 u8 addr2[6]; /* filled by firmware */
100 u8 addr3[6];
101 u16 seq_ctrl; /* filled by firmware */
102 u8 addr4[6];
103 u16 data_len;
104
105 /* 802.3 */
106 u8 dst_addr[6];
107 u8 src_addr[6];
108 u16 len;
109
110 /* followed by frame data; max 2304 bytes */
111} __attribute__ ((packed));
112
113
114struct hfa384x_rid_hdr
115{
116 u16 len;
117 u16 rid;
118} __attribute__ ((packed));
119
120
121/* Macro for converting signal levels (range 27 .. 154) to wireless ext
122 * dBm value with some accuracy */
123#define HFA384X_LEVEL_TO_dBm(v) 0x100 + (v) * 100 / 255 - 100
124
125#define HFA384X_LEVEL_TO_dBm_sign(v) (v) * 100 / 255 - 100
126
127struct hfa384x_scan_request {
128 u16 channel_list;
129 u16 txrate; /* HFA384X_RATES_* */
130} __attribute__ ((packed));
131
132struct hfa384x_hostscan_request {
133 u16 channel_list;
134 u16 txrate;
135 u16 target_ssid_len;
136 u8 target_ssid[32];
137} __attribute__ ((packed));
138
139struct hfa384x_join_request {
140 u8 bssid[6];
141 u16 channel;
142} __attribute__ ((packed));
143
144struct hfa384x_info_frame {
145 u16 len;
146 u16 type;
147} __attribute__ ((packed));
148
149struct hfa384x_comm_tallies {
150 u16 tx_unicast_frames;
151 u16 tx_multicast_frames;
152 u16 tx_fragments;
153 u16 tx_unicast_octets;
154 u16 tx_multicast_octets;
155 u16 tx_deferred_transmissions;
156 u16 tx_single_retry_frames;
157 u16 tx_multiple_retry_frames;
158 u16 tx_retry_limit_exceeded;
159 u16 tx_discards;
160 u16 rx_unicast_frames;
161 u16 rx_multicast_frames;
162 u16 rx_fragments;
163 u16 rx_unicast_octets;
164 u16 rx_multicast_octets;
165 u16 rx_fcs_errors;
166 u16 rx_discards_no_buffer;
167 u16 tx_discards_wrong_sa;
168 u16 rx_discards_wep_undecryptable;
169 u16 rx_message_in_msg_fragments;
170 u16 rx_message_in_bad_msg_fragments;
171} __attribute__ ((packed));
172
173struct hfa384x_comm_tallies32 {
174 u32 tx_unicast_frames;
175 u32 tx_multicast_frames;
176 u32 tx_fragments;
177 u32 tx_unicast_octets;
178 u32 tx_multicast_octets;
179 u32 tx_deferred_transmissions;
180 u32 tx_single_retry_frames;
181 u32 tx_multiple_retry_frames;
182 u32 tx_retry_limit_exceeded;
183 u32 tx_discards;
184 u32 rx_unicast_frames;
185 u32 rx_multicast_frames;
186 u32 rx_fragments;
187 u32 rx_unicast_octets;
188 u32 rx_multicast_octets;
189 u32 rx_fcs_errors;
190 u32 rx_discards_no_buffer;
191 u32 tx_discards_wrong_sa;
192 u32 rx_discards_wep_undecryptable;
193 u32 rx_message_in_msg_fragments;
194 u32 rx_message_in_bad_msg_fragments;
195} __attribute__ ((packed));
196
197struct hfa384x_scan_result_hdr {
198 u16 reserved;
199 u16 scan_reason;
200#define HFA384X_SCAN_IN_PROGRESS 0 /* no results available yet */
201#define HFA384X_SCAN_HOST_INITIATED 1
202#define HFA384X_SCAN_FIRMWARE_INITIATED 2
203#define HFA384X_SCAN_INQUIRY_FROM_HOST 3
204} __attribute__ ((packed));
205
206#define HFA384X_SCAN_MAX_RESULTS 32
207
208struct hfa384x_scan_result {
209 u16 chid;
210 u16 anl;
211 u16 sl;
212 u8 bssid[6];
213 u16 beacon_interval;
214 u16 capability;
215 u16 ssid_len;
216 u8 ssid[32];
217 u8 sup_rates[10];
218 u16 rate;
219} __attribute__ ((packed));
220
221struct hfa384x_hostscan_result {
222 u16 chid;
223 u16 anl;
224 u16 sl;
225 u8 bssid[6];
226 u16 beacon_interval;
227 u16 capability;
228 u16 ssid_len;
229 u8 ssid[32];
230 u8 sup_rates[10];
231 u16 rate;
232 u16 atim;
233} __attribute__ ((packed));
234
235struct comm_tallies_sums {
236 unsigned int tx_unicast_frames;
237 unsigned int tx_multicast_frames;
238 unsigned int tx_fragments;
239 unsigned int tx_unicast_octets;
240 unsigned int tx_multicast_octets;
241 unsigned int tx_deferred_transmissions;
242 unsigned int tx_single_retry_frames;
243 unsigned int tx_multiple_retry_frames;
244 unsigned int tx_retry_limit_exceeded;
245 unsigned int tx_discards;
246 unsigned int rx_unicast_frames;
247 unsigned int rx_multicast_frames;
248 unsigned int rx_fragments;
249 unsigned int rx_unicast_octets;
250 unsigned int rx_multicast_octets;
251 unsigned int rx_fcs_errors;
252 unsigned int rx_discards_no_buffer;
253 unsigned int tx_discards_wrong_sa;
254 unsigned int rx_discards_wep_undecryptable;
255 unsigned int rx_message_in_msg_fragments;
256 unsigned int rx_message_in_bad_msg_fragments;
257};
258
259
260struct hfa384x_regs {
261 u16 cmd;
262 u16 evstat;
263 u16 offset0;
264 u16 offset1;
265 u16 swsupport0;
266};
267
268
269#if defined(PRISM2_PCCARD) || defined(PRISM2_PLX)
270/* I/O ports for HFA384X Controller access */
271#define HFA384X_CMD_OFF 0x00
272#define HFA384X_PARAM0_OFF 0x02
273#define HFA384X_PARAM1_OFF 0x04
274#define HFA384X_PARAM2_OFF 0x06
275#define HFA384X_STATUS_OFF 0x08
276#define HFA384X_RESP0_OFF 0x0A
277#define HFA384X_RESP1_OFF 0x0C
278#define HFA384X_RESP2_OFF 0x0E
279#define HFA384X_INFOFID_OFF 0x10
280#define HFA384X_CONTROL_OFF 0x14
281#define HFA384X_SELECT0_OFF 0x18
282#define HFA384X_SELECT1_OFF 0x1A
283#define HFA384X_OFFSET0_OFF 0x1C
284#define HFA384X_OFFSET1_OFF 0x1E
285#define HFA384X_RXFID_OFF 0x20
286#define HFA384X_ALLOCFID_OFF 0x22
287#define HFA384X_TXCOMPLFID_OFF 0x24
288#define HFA384X_SWSUPPORT0_OFF 0x28
289#define HFA384X_SWSUPPORT1_OFF 0x2A
290#define HFA384X_SWSUPPORT2_OFF 0x2C
291#define HFA384X_EVSTAT_OFF 0x30
292#define HFA384X_INTEN_OFF 0x32
293#define HFA384X_EVACK_OFF 0x34
294#define HFA384X_DATA0_OFF 0x36
295#define HFA384X_DATA1_OFF 0x38
296#define HFA384X_AUXPAGE_OFF 0x3A
297#define HFA384X_AUXOFFSET_OFF 0x3C
298#define HFA384X_AUXDATA_OFF 0x3E
299#endif /* PRISM2_PCCARD || PRISM2_PLX */
300
301#ifdef PRISM2_PCI
302/* Memory addresses for ISL3874 controller access */
303#define HFA384X_CMD_OFF 0x00
304#define HFA384X_PARAM0_OFF 0x04
305#define HFA384X_PARAM1_OFF 0x08
306#define HFA384X_PARAM2_OFF 0x0C
307#define HFA384X_STATUS_OFF 0x10
308#define HFA384X_RESP0_OFF 0x14
309#define HFA384X_RESP1_OFF 0x18
310#define HFA384X_RESP2_OFF 0x1C
311#define HFA384X_INFOFID_OFF 0x20
312#define HFA384X_CONTROL_OFF 0x28
313#define HFA384X_SELECT0_OFF 0x30
314#define HFA384X_SELECT1_OFF 0x34
315#define HFA384X_OFFSET0_OFF 0x38
316#define HFA384X_OFFSET1_OFF 0x3C
317#define HFA384X_RXFID_OFF 0x40
318#define HFA384X_ALLOCFID_OFF 0x44
319#define HFA384X_TXCOMPLFID_OFF 0x48
320#define HFA384X_PCICOR_OFF 0x4C
321#define HFA384X_SWSUPPORT0_OFF 0x50
322#define HFA384X_SWSUPPORT1_OFF 0x54
323#define HFA384X_SWSUPPORT2_OFF 0x58
324#define HFA384X_PCIHCR_OFF 0x5C
325#define HFA384X_EVSTAT_OFF 0x60
326#define HFA384X_INTEN_OFF 0x64
327#define HFA384X_EVACK_OFF 0x68
328#define HFA384X_DATA0_OFF 0x6C
329#define HFA384X_DATA1_OFF 0x70
330#define HFA384X_AUXPAGE_OFF 0x74
331#define HFA384X_AUXOFFSET_OFF 0x78
332#define HFA384X_AUXDATA_OFF 0x7C
333#define HFA384X_PCI_M0_ADDRH_OFF 0x80
334#define HFA384X_PCI_M0_ADDRL_OFF 0x84
335#define HFA384X_PCI_M0_LEN_OFF 0x88
336#define HFA384X_PCI_M0_CTL_OFF 0x8C
337#define HFA384X_PCI_STATUS_OFF 0x98
338#define HFA384X_PCI_M1_ADDRH_OFF 0xA0
339#define HFA384X_PCI_M1_ADDRL_OFF 0xA4
340#define HFA384X_PCI_M1_LEN_OFF 0xA8
341#define HFA384X_PCI_M1_CTL_OFF 0xAC
342
343/* PCI bus master control bits (these are undocumented; based on guessing and
344 * experimenting..) */
345#define HFA384X_PCI_CTL_FROM_BAP (BIT(5) | BIT(1) | BIT(0))
346#define HFA384X_PCI_CTL_TO_BAP (BIT(5) | BIT(0))
347
348#endif /* PRISM2_PCI */
349
350
351/* Command codes for CMD reg. */
352#define HFA384X_CMDCODE_INIT 0x00
353#define HFA384X_CMDCODE_ENABLE 0x01
354#define HFA384X_CMDCODE_DISABLE 0x02
355#define HFA384X_CMDCODE_ALLOC 0x0A
356#define HFA384X_CMDCODE_TRANSMIT 0x0B
357#define HFA384X_CMDCODE_INQUIRE 0x11
358#define HFA384X_CMDCODE_ACCESS 0x21
359#define HFA384X_CMDCODE_ACCESS_WRITE (0x21 | BIT(8))
360#define HFA384X_CMDCODE_DOWNLOAD 0x22
361#define HFA384X_CMDCODE_READMIF 0x30
362#define HFA384X_CMDCODE_WRITEMIF 0x31
363#define HFA384X_CMDCODE_TEST 0x38
364
365#define HFA384X_CMDCODE_MASK 0x3F
366
367/* Test mode operations */
368#define HFA384X_TEST_CHANGE_CHANNEL 0x08
369#define HFA384X_TEST_MONITOR 0x0B
370#define HFA384X_TEST_STOP 0x0F
371#define HFA384X_TEST_CFG_BITS 0x15
372#define HFA384X_TEST_CFG_BIT_ALC BIT(3)
373
374#define HFA384X_CMD_BUSY BIT(15)
375
376#define HFA384X_CMD_TX_RECLAIM BIT(8)
377
378#define HFA384X_OFFSET_ERR BIT(14)
379#define HFA384X_OFFSET_BUSY BIT(15)
380
381
382/* ProgMode for download command */
383#define HFA384X_PROGMODE_DISABLE 0
384#define HFA384X_PROGMODE_ENABLE_VOLATILE 1
385#define HFA384X_PROGMODE_ENABLE_NON_VOLATILE 2
386#define HFA384X_PROGMODE_PROGRAM_NON_VOLATILE 3
387
388#define HFA384X_AUX_MAGIC0 0xfe01
389#define HFA384X_AUX_MAGIC1 0xdc23
390#define HFA384X_AUX_MAGIC2 0xba45
391
392#define HFA384X_AUX_PORT_DISABLED 0
393#define HFA384X_AUX_PORT_DISABLE BIT(14)
394#define HFA384X_AUX_PORT_ENABLE BIT(15)
395#define HFA384X_AUX_PORT_ENABLED (BIT(14) | BIT(15))
396#define HFA384X_AUX_PORT_MASK (BIT(14) | BIT(15))
397
398#define PRISM2_PDA_SIZE 1024
399
400
401/* Events; EvStat, Interrupt mask (IntEn), and acknowledge bits (EvAck) */
402#define HFA384X_EV_TICK BIT(15)
403#define HFA384X_EV_WTERR BIT(14)
404#define HFA384X_EV_INFDROP BIT(13)
405#ifdef PRISM2_PCI
406#define HFA384X_EV_PCI_M1 BIT(9)
407#define HFA384X_EV_PCI_M0 BIT(8)
408#endif /* PRISM2_PCI */
409#define HFA384X_EV_INFO BIT(7)
410#define HFA384X_EV_DTIM BIT(5)
411#define HFA384X_EV_CMD BIT(4)
412#define HFA384X_EV_ALLOC BIT(3)
413#define HFA384X_EV_TXEXC BIT(2)
414#define HFA384X_EV_TX BIT(1)
415#define HFA384X_EV_RX BIT(0)
416
417
418/* HFA384X Information frames */
419#define HFA384X_INFO_HANDOVERADDR 0xF000 /* AP f/w ? */
420#define HFA384X_INFO_HANDOVERDEAUTHADDR 0xF001 /* AP f/w 1.3.7 */
421#define HFA384X_INFO_COMMTALLIES 0xF100
422#define HFA384X_INFO_SCANRESULTS 0xF101
423#define HFA384X_INFO_CHANNELINFORESULTS 0xF102 /* AP f/w only */
424#define HFA384X_INFO_HOSTSCANRESULTS 0xF103
425#define HFA384X_INFO_LINKSTATUS 0xF200
426#define HFA384X_INFO_ASSOCSTATUS 0xF201 /* ? */
427#define HFA384X_INFO_AUTHREQ 0xF202 /* ? */
428#define HFA384X_INFO_PSUSERCNT 0xF203 /* ? */
429#define HFA384X_INFO_KEYIDCHANGED 0xF204 /* ? */
430
431enum { HFA384X_LINKSTATUS_CONNECTED = 1,
432 HFA384X_LINKSTATUS_DISCONNECTED = 2,
433 HFA384X_LINKSTATUS_AP_CHANGE = 3,
434 HFA384X_LINKSTATUS_AP_OUT_OF_RANGE = 4,
435 HFA384X_LINKSTATUS_AP_IN_RANGE = 5,
436 HFA384X_LINKSTATUS_ASSOC_FAILED = 6 };
437
438enum { HFA384X_PORTTYPE_BSS = 1, HFA384X_PORTTYPE_WDS = 2,
439 HFA384X_PORTTYPE_PSEUDO_IBSS = 3, HFA384X_PORTTYPE_IBSS = 0,
440 HFA384X_PORTTYPE_HOSTAP = 6 };
441
442#define HFA384X_RATES_1MBPS BIT(0)
443#define HFA384X_RATES_2MBPS BIT(1)
444#define HFA384X_RATES_5MBPS BIT(2)
445#define HFA384X_RATES_11MBPS BIT(3)
446
447#define HFA384X_ROAMING_FIRMWARE 1
448#define HFA384X_ROAMING_HOST 2
449#define HFA384X_ROAMING_DISABLED 3
450
451#define HFA384X_WEPFLAGS_PRIVACYINVOKED BIT(0)
452#define HFA384X_WEPFLAGS_EXCLUDEUNENCRYPTED BIT(1)
453#define HFA384X_WEPFLAGS_HOSTENCRYPT BIT(4)
454#define HFA384X_WEPFLAGS_HOSTDECRYPT BIT(7)
455
456#define HFA384X_RX_STATUS_MSGTYPE (BIT(15) | BIT(14) | BIT(13))
457#define HFA384X_RX_STATUS_PCF BIT(12)
458#define HFA384X_RX_STATUS_MACPORT (BIT(10) | BIT(9) | BIT(8))
459#define HFA384X_RX_STATUS_UNDECR BIT(1)
460#define HFA384X_RX_STATUS_FCSERR BIT(0)
461
462#define HFA384X_RX_STATUS_GET_MSGTYPE(s) \
463(((s) & HFA384X_RX_STATUS_MSGTYPE) >> 13)
464#define HFA384X_RX_STATUS_GET_MACPORT(s) \
465(((s) & HFA384X_RX_STATUS_MACPORT) >> 8)
466
467enum { HFA384X_RX_MSGTYPE_NORMAL = 0, HFA384X_RX_MSGTYPE_RFC1042 = 1,
468 HFA384X_RX_MSGTYPE_BRIDGETUNNEL = 2, HFA384X_RX_MSGTYPE_MGMT = 4 };
469
470
471#define HFA384X_TX_CTRL_ALT_RTRY BIT(5)
472#define HFA384X_TX_CTRL_802_11 BIT(3)
473#define HFA384X_TX_CTRL_802_3 0
474#define HFA384X_TX_CTRL_TX_EX BIT(2)
475#define HFA384X_TX_CTRL_TX_OK BIT(1)
476
477#define HFA384X_TX_STATUS_RETRYERR BIT(0)
478#define HFA384X_TX_STATUS_AGEDERR BIT(1)
479#define HFA384X_TX_STATUS_DISCON BIT(2)
480#define HFA384X_TX_STATUS_FORMERR BIT(3)
481
482/* HFA3861/3863 (BBP) Control Registers */
483#define HFA386X_CR_TX_CONFIGURE 0x12 /* CR9 */
484#define HFA386X_CR_RX_CONFIGURE 0x14 /* CR10 */
485#define HFA386X_CR_A_D_TEST_MODES2 0x1A /* CR13 */
486#define HFA386X_CR_MANUAL_TX_POWER 0x3E /* CR31 */
487#define HFA386X_CR_MEASURED_TX_POWER 0x74 /* CR58 */
488
489
490#ifdef __KERNEL__
491
492#define PRISM2_TXFID_COUNT 8
493#define PRISM2_DATA_MAXLEN 2304
494#define PRISM2_TXFID_LEN (PRISM2_DATA_MAXLEN + sizeof(struct hfa384x_tx_frame))
495#define PRISM2_TXFID_EMPTY 0xffff
496#define PRISM2_TXFID_RESERVED 0xfffe
497#define PRISM2_DUMMY_FID 0xffff
498#define MAX_SSID_LEN 32
499#define MAX_NAME_LEN 32 /* this is assumed to be equal to MAX_SSID_LEN */
500
501#define PRISM2_DUMP_RX_HDR BIT(0)
502#define PRISM2_DUMP_TX_HDR BIT(1)
503#define PRISM2_DUMP_TXEXC_HDR BIT(2)
504
505struct hostap_tx_callback_info {
506 u16 idx;
507 void (*func)(struct sk_buff *, int ok, void *);
508 void *data;
509 struct hostap_tx_callback_info *next;
510};
511
512
513/* IEEE 802.11 requires that STA supports concurrent reception of at least
514 * three fragmented frames. This define can be increased to support more
515 * concurrent frames, but it should be noted that each entry can consume about
516 * 2 kB of RAM and increasing cache size will slow down frame reassembly. */
517#define PRISM2_FRAG_CACHE_LEN 4
518
519struct prism2_frag_entry {
520 unsigned long first_frag_time;
521 unsigned int seq;
522 unsigned int last_frag;
523 struct sk_buff *skb;
524 u8 src_addr[ETH_ALEN];
525 u8 dst_addr[ETH_ALEN];
526};
527
528
529struct hostap_cmd_queue {
530 struct list_head list;
531 wait_queue_head_t compl;
532 volatile enum { CMD_SLEEP, CMD_CALLBACK, CMD_COMPLETED } type;
533 void (*callback)(struct net_device *dev, long context, u16 resp0,
534 u16 res);
535 long context;
536 u16 cmd, param0, param1;
537 u16 resp0, res;
538 volatile int issued, issuing;
539
540 atomic_t usecnt;
541 int del_req;
542};
543
544/* options for hw_shutdown */
545#define HOSTAP_HW_NO_DISABLE BIT(0)
546#define HOSTAP_HW_ENABLE_CMDCOMPL BIT(1)
547
548typedef struct local_info local_info_t;
549
550struct prism2_helper_functions {
551 /* these functions are defined in hardware model specific files
552 * (hostap_{cs,plx,pci}.c */
553 int (*card_present)(local_info_t *local);
554 void (*cor_sreset)(local_info_t *local);
555 int (*dev_open)(local_info_t *local);
556 int (*dev_close)(local_info_t *local);
557 void (*genesis_reset)(local_info_t *local, int hcr);
558
559 /* the following functions are from hostap_hw.c, but they may have some
560 * hardware model specific code */
561
562 /* FIX: low-level commands like cmd might disappear at some point to
563 * make it easier to change them if needed (e.g., cmd would be replaced
564 * with write_mif/read_mif/testcmd/inquire); at least get_rid and
565 * set_rid might move to hostap_{cs,plx,pci}.c */
566 int (*cmd)(struct net_device *dev, u16 cmd, u16 param0, u16 *param1,
567 u16 *resp0);
568 void (*read_regs)(struct net_device *dev, struct hfa384x_regs *regs);
569 int (*get_rid)(struct net_device *dev, u16 rid, void *buf, int len,
570 int exact_len);
571 int (*set_rid)(struct net_device *dev, u16 rid, void *buf, int len);
572 int (*hw_enable)(struct net_device *dev, int initial);
573 int (*hw_config)(struct net_device *dev, int initial);
574 void (*hw_reset)(struct net_device *dev);
575 void (*hw_shutdown)(struct net_device *dev, int no_disable);
576 int (*reset_port)(struct net_device *dev);
577 void (*schedule_reset)(local_info_t *local);
578 int (*download)(local_info_t *local,
579 struct prism2_download_param *param);
580 int (*tx)(struct sk_buff *skb, struct net_device *dev);
581 int (*set_tim)(struct net_device *dev, int aid, int set);
582 int (*read_aux)(struct net_device *dev, unsigned addr, int len,
583 u8 *buf);
584
585 int need_tx_headroom; /* number of bytes of headroom needed before
586 * IEEE 802.11 header */
587 enum { HOSTAP_HW_PCCARD, HOSTAP_HW_PLX, HOSTAP_HW_PCI } hw_type;
588};
589
590
591struct prism2_download_data {
592 u32 dl_cmd;
593 u32 start_addr;
594 u32 num_areas;
595 struct prism2_download_data_area {
596 u32 addr; /* wlan card address */
597 u32 len;
598 u8 *data; /* allocated data */
599 } data[0];
600};
601
602
603#define HOSTAP_MAX_BSS_COUNT 64
604#define MAX_WPA_IE_LEN 64
605
606struct hostap_bss_info {
607 struct list_head list;
608 unsigned long last_update;
609 unsigned int count;
610 u8 bssid[ETH_ALEN];
611 u16 capab_info;
612 u8 ssid[32];
613 size_t ssid_len;
614 u8 wpa_ie[MAX_WPA_IE_LEN];
615 size_t wpa_ie_len;
616 u8 rsn_ie[MAX_WPA_IE_LEN];
617 size_t rsn_ie_len;
618 int chan;
619 int included;
620};
621
622
623/* Per radio private Host AP data - shared by all net devices interfaces used
624 * by each radio (wlan#, wlan#ap, wlan#sta, WDS).
625 * ((struct hostap_interface *) netdev_priv(dev))->local points to this
626 * structure. */
627struct local_info {
628 struct module *hw_module;
629 int card_idx;
630 int dev_enabled;
631 int master_dev_auto_open; /* was master device opened automatically */
632 int num_dev_open; /* number of open devices */
633 struct net_device *dev; /* master radio device */
634 struct net_device *ddev; /* main data device */
635 struct list_head hostap_interfaces; /* Host AP interface list (contains
636 * struct hostap_interface entries)
637 */
638 rwlock_t iface_lock; /* hostap_interfaces read lock; use write lock
639 * when removing entries from the list.
640 * TX and RX paths can use read lock. */
641 spinlock_t cmdlock, baplock, lock;
642 struct semaphore rid_bap_sem;
643 u16 infofid; /* MAC buffer id for info frame */
644 /* txfid, intransmitfid, next_txtid, and next_alloc are protected by
645 * txfidlock */
646 spinlock_t txfidlock;
647 int txfid_len; /* length of allocated TX buffers */
648 u16 txfid[PRISM2_TXFID_COUNT]; /* buffer IDs for TX frames */
649 /* buffer IDs for intransmit frames or PRISM2_TXFID_EMPTY if
650 * corresponding txfid is free for next TX frame */
651 u16 intransmitfid[PRISM2_TXFID_COUNT];
652 int next_txfid; /* index to the next txfid to be checked for
653 * availability */
654 int next_alloc; /* index to the next intransmitfid to be checked for
655 * allocation events */
656
657 /* bitfield for atomic bitops */
658#define HOSTAP_BITS_TRANSMIT 0
659#define HOSTAP_BITS_BAP_TASKLET 1
660#define HOSTAP_BITS_BAP_TASKLET2 2
661 long bits;
662
663 struct ap_data *ap;
664
665 char essid[MAX_SSID_LEN + 1];
666 char name[MAX_NAME_LEN + 1];
667 int name_set;
668 u16 channel_mask; /* mask of allowed channels */
669 u16 scan_channel_mask; /* mask of channels to be scanned */
670 struct comm_tallies_sums comm_tallies;
671 struct net_device_stats stats;
672 struct proc_dir_entry *proc;
673 int iw_mode; /* operating mode (IW_MODE_*) */
674 int pseudo_adhoc; /* 0: IW_MODE_ADHOC is real 802.11 compliant IBSS
675 * 1: IW_MODE_ADHOC is "pseudo IBSS" */
676 char bssid[ETH_ALEN];
677 int channel;
678 int beacon_int;
679 int dtim_period;
680 int mtu;
681 int frame_dump; /* dump RX/TX frame headers, PRISM2_DUMP_ flags */
682 int fw_tx_rate_control;
683 u16 tx_rate_control;
684 u16 basic_rates;
685 int hw_resetting;
686 int hw_ready;
687 int hw_reset_tries; /* how many times reset has been tried */
688 int hw_downloading;
689 int shutdown;
690 int pri_only;
691 int no_pri; /* no PRI f/w present */
692 int sram_type; /* 8 = x8 SRAM, 16 = x16 SRAM, -1 = unknown */
693
694 enum {
695 PRISM2_TXPOWER_AUTO = 0, PRISM2_TXPOWER_OFF,
696 PRISM2_TXPOWER_FIXED, PRISM2_TXPOWER_UNKNOWN
697 } txpower_type;
698 int txpower; /* if txpower_type == PRISM2_TXPOWER_FIXED */
699
700 /* command queue for hfa384x_cmd(); protected with cmdlock */
701 struct list_head cmd_queue;
702 /* max_len for cmd_queue; in addition, cmd_callback can use two
703 * additional entries to prevent sleeping commands from stopping
704 * transmits */
705#define HOSTAP_CMD_QUEUE_MAX_LEN 16
706 int cmd_queue_len; /* number of entries in cmd_queue */
707
708 /* if card timeout is detected in interrupt context, reset_queue is
709 * used to schedule card reseting to be done in user context */
710 struct work_struct reset_queue;
711
712 /* For scheduling a change of the promiscuous mode RID */
713 int is_promisc;
714 struct work_struct set_multicast_list_queue;
715
716 struct work_struct set_tim_queue;
717 struct list_head set_tim_list;
718 spinlock_t set_tim_lock;
719
720 int wds_max_connections;
721 int wds_connections;
722#define HOSTAP_WDS_BROADCAST_RA BIT(0)
723#define HOSTAP_WDS_AP_CLIENT BIT(1)
724#define HOSTAP_WDS_STANDARD_FRAME BIT(2)
725 u32 wds_type;
726 u16 tx_control; /* flags to be used in TX description */
727 int manual_retry_count; /* -1 = use f/w default; otherwise retry count
728 * to be used with all frames */
729
730 struct iw_statistics wstats;
731 unsigned long scan_timestamp; /* Time started to scan */
732 enum {
733 PRISM2_MONITOR_80211 = 0, PRISM2_MONITOR_PRISM = 1,
734 PRISM2_MONITOR_CAPHDR = 2
735 } monitor_type;
736 int (*saved_eth_header_parse)(struct sk_buff *skb,
737 unsigned char *haddr);
738 int monitor_allow_fcserr;
739
740 int hostapd; /* whether user space daemon, hostapd, is used for AP
741 * management */
742 int hostapd_sta; /* whether hostapd is used with an extra STA interface
743 */
744 struct net_device *apdev;
745 struct net_device_stats apdevstats;
746
747 char assoc_ap_addr[ETH_ALEN];
748 struct net_device *stadev;
749 struct net_device_stats stadevstats;
750
751#define WEP_KEYS 4
752#define WEP_KEY_LEN 13
753 struct ieee80211_crypt_data *crypt[WEP_KEYS];
754 int tx_keyidx; /* default TX key index (crypt[tx_keyidx]) */
755 struct timer_list crypt_deinit_timer;
756 struct list_head crypt_deinit_list;
757
758 int open_wep; /* allow unencrypted frames */
759 int host_encrypt;
760 int host_decrypt;
761 int privacy_invoked; /* force privacy invoked flag even if no keys are
762 * configured */
763 int fw_encrypt_ok; /* whether firmware-based WEP encrypt is working
764 * in Host AP mode (STA f/w 1.4.9 or newer) */
765 int bcrx_sta_key; /* use individual keys to override default keys even
766 * with RX of broad/multicast frames */
767
768 struct prism2_frag_entry frag_cache[PRISM2_FRAG_CACHE_LEN];
769 unsigned int frag_next_idx;
770
771 int ieee_802_1x; /* is IEEE 802.1X used */
772
773 int antsel_tx, antsel_rx;
774 int rts_threshold; /* dot11RTSThreshold */
775 int fragm_threshold; /* dot11FragmentationThreshold */
776 int auth_algs; /* PRISM2_AUTH_ flags */
777
778 int enh_sec; /* cnfEnhSecurity options (broadcast SSID hide/ignore) */
779 int tallies32; /* 32-bit tallies in use */
780
781 struct prism2_helper_functions *func;
782
783 u8 *pda;
784 int fw_ap;
785#define PRISM2_FW_VER(major, minor, variant) \
786(((major) << 16) | ((minor) << 8) | variant)
787 u32 sta_fw_ver;
788
789 /* Tasklets for handling hardware IRQ related operations outside hw IRQ
790 * handler */
791 struct tasklet_struct bap_tasklet;
792
793 struct tasklet_struct info_tasklet;
794 struct sk_buff_head info_list; /* info frames as skb's for
795 * info_tasklet */
796
797 struct hostap_tx_callback_info *tx_callback; /* registered TX callbacks
798 */
799
800 struct tasklet_struct rx_tasklet;
801 struct sk_buff_head rx_list;
802
803 struct tasklet_struct sta_tx_exc_tasklet;
804 struct sk_buff_head sta_tx_exc_list;
805
806 int host_roaming;
807 unsigned long last_join_time; /* time of last JoinRequest */
808 struct hfa384x_hostscan_result *last_scan_results;
809 int last_scan_results_count;
810 enum { PRISM2_SCAN, PRISM2_HOSTSCAN } last_scan_type;
811 struct work_struct info_queue;
812 long pending_info; /* bit field of pending info_queue items */
813#define PRISM2_INFO_PENDING_LINKSTATUS 0
814#define PRISM2_INFO_PENDING_SCANRESULTS 1
815 int prev_link_status; /* previous received LinkStatus info */
816 int prev_linkstatus_connected;
817 u8 preferred_ap[6]; /* use this AP if possible */
818
819#ifdef PRISM2_CALLBACK
820 void *callback_data; /* Can be used in callbacks; e.g., allocate
821 * on enable event and free on disable event.
822 * Host AP driver code does not touch this. */
823#endif /* PRISM2_CALLBACK */
824
825 wait_queue_head_t hostscan_wq;
826
827 /* Passive scan in Host AP mode */
828 struct timer_list passive_scan_timer;
829 int passive_scan_interval; /* in seconds, 0 = disabled */
830 int passive_scan_channel;
831 enum { PASSIVE_SCAN_WAIT, PASSIVE_SCAN_LISTEN } passive_scan_state;
832
833 struct timer_list tick_timer;
834 unsigned long last_tick_timer;
835 unsigned int sw_tick_stuck;
836
837 /* commsQuality / dBmCommsQuality data from periodic polling; only
838 * valid for Managed and Ad-hoc modes */
839 unsigned long last_comms_qual_update;
840 int comms_qual; /* in some odd unit.. */
841 int avg_signal; /* in dB (note: negative) */
842 int avg_noise; /* in dB (note: negative) */
843 struct work_struct comms_qual_update;
844
845 /* RSSI to dBm adjustment (for RX descriptor fields) */
846 int rssi_to_dBm; /* substract from RSSI to get approximate dBm value */
847
848 /* BSS list / protected by local->lock */
849 struct list_head bss_list;
850 int num_bss_info;
851 int wpa; /* WPA support enabled */
852 int tkip_countermeasures;
853 int drop_unencrypted;
854 /* Generic IEEE 802.11 info element to be added to
855 * ProbeResp/Beacon/(Re)AssocReq */
856 u8 *generic_elem;
857 size_t generic_elem_len;
858
859#ifdef PRISM2_DOWNLOAD_SUPPORT
860 /* Persistent volatile download data */
861 struct prism2_download_data *dl_pri;
862 struct prism2_download_data *dl_sec;
863#endif /* PRISM2_DOWNLOAD_SUPPORT */
864
865#ifdef PRISM2_IO_DEBUG
866#define PRISM2_IO_DEBUG_SIZE 10000
867 u32 io_debug[PRISM2_IO_DEBUG_SIZE];
868 int io_debug_head;
869 int io_debug_enabled;
870#endif /* PRISM2_IO_DEBUG */
871
872 /* Pointer to hardware model specific (cs,pci,plx) private data. */
873 void *hw_priv;
874};
875
876
877/* Per interface private Host AP data
878 * Allocated for each net device that Host AP uses (wlan#, wlan#ap, wlan#sta,
879 * WDS) and netdev_priv(dev) points to this structure. */
880struct hostap_interface {
881 struct list_head list; /* list entry in Host AP interface list */
882 struct net_device *dev; /* pointer to this device */
883 struct local_info *local; /* pointer to shared private data */
884 struct net_device_stats stats;
885 struct iw_spy_data spy_data; /* iwspy support */
886 struct iw_public_data wireless_data;
887
888 enum {
889 HOSTAP_INTERFACE_MASTER,
890 HOSTAP_INTERFACE_MAIN,
891 HOSTAP_INTERFACE_AP,
892 HOSTAP_INTERFACE_STA,
893 HOSTAP_INTERFACE_WDS,
894 } type;
895
896 union {
897 struct hostap_interface_wds {
898 u8 remote_addr[ETH_ALEN];
899 } wds;
900 } u;
901};
902
903
904#define HOSTAP_SKB_TX_DATA_MAGIC 0xf08a36a2
905
906/*
907 * TX meta data - stored in skb->cb buffer, so this must not be increased over
908 * the 40-byte limit
909 */
910struct hostap_skb_tx_data {
911 u32 magic; /* HOSTAP_SKB_TX_DATA_MAGIC */
912 u8 rate; /* transmit rate */
913#define HOSTAP_TX_FLAGS_WDS BIT(0)
914#define HOSTAP_TX_FLAGS_BUFFERED_FRAME BIT(1)
915#define HOSTAP_TX_FLAGS_ADD_MOREDATA BIT(2)
916 u8 flags; /* HOSTAP_TX_FLAGS_* */
917 u16 tx_cb_idx;
918 struct hostap_interface *iface;
919 unsigned long jiffies; /* queueing timestamp */
920 unsigned short ethertype;
921};
922
923
924#ifndef PRISM2_NO_DEBUG
925
926#define DEBUG_FID BIT(0)
927#define DEBUG_PS BIT(1)
928#define DEBUG_FLOW BIT(2)
929#define DEBUG_AP BIT(3)
930#define DEBUG_HW BIT(4)
931#define DEBUG_EXTRA BIT(5)
932#define DEBUG_EXTRA2 BIT(6)
933#define DEBUG_PS2 BIT(7)
934#define DEBUG_MASK (DEBUG_PS | DEBUG_AP | DEBUG_HW | DEBUG_EXTRA)
935#define PDEBUG(n, args...) \
936do { if ((n) & DEBUG_MASK) printk(KERN_DEBUG args); } while (0)
937#define PDEBUG2(n, args...) \
938do { if ((n) & DEBUG_MASK) printk(args); } while (0)
939
940#else /* PRISM2_NO_DEBUG */
941
942#define PDEBUG(n, args...)
943#define PDEBUG2(n, args...)
944
945#endif /* PRISM2_NO_DEBUG */
946
947enum { BAP0 = 0, BAP1 = 1 };
948
949#define PRISM2_IO_DEBUG_CMD_INB 0
950#define PRISM2_IO_DEBUG_CMD_INW 1
951#define PRISM2_IO_DEBUG_CMD_INSW 2
952#define PRISM2_IO_DEBUG_CMD_OUTB 3
953#define PRISM2_IO_DEBUG_CMD_OUTW 4
954#define PRISM2_IO_DEBUG_CMD_OUTSW 5
955#define PRISM2_IO_DEBUG_CMD_ERROR 6
956#define PRISM2_IO_DEBUG_CMD_INTERRUPT 7
957
958#ifdef PRISM2_IO_DEBUG
959
960#define PRISM2_IO_DEBUG_ENTRY(cmd, reg, value) \
961(((cmd) << 24) | ((reg) << 16) | value)
962
963static inline void prism2_io_debug_add(struct net_device *dev, int cmd,
964 int reg, int value)
965{
966 struct hostap_interface *iface = netdev_priv(dev);
967 local_info_t *local = iface->local;
968
969 if (!local->io_debug_enabled)
970 return;
971
972 local->io_debug[local->io_debug_head] = jiffies & 0xffffffff;
973 if (++local->io_debug_head >= PRISM2_IO_DEBUG_SIZE)
974 local->io_debug_head = 0;
975 local->io_debug[local->io_debug_head] =
976 PRISM2_IO_DEBUG_ENTRY(cmd, reg, value);
977 if (++local->io_debug_head >= PRISM2_IO_DEBUG_SIZE)
978 local->io_debug_head = 0;
979}
980
981
982static inline void prism2_io_debug_error(struct net_device *dev, int err)
983{
984 struct hostap_interface *iface = netdev_priv(dev);
985 local_info_t *local = iface->local;
986 unsigned long flags;
987
988 if (!local->io_debug_enabled)
989 return;
990
991 spin_lock_irqsave(&local->lock, flags);
992 prism2_io_debug_add(dev, PRISM2_IO_DEBUG_CMD_ERROR, 0, err);
993 if (local->io_debug_enabled == 1) {
994 local->io_debug_enabled = 0;
995 printk(KERN_DEBUG "%s: I/O debug stopped\n", dev->name);
996 }
997 spin_unlock_irqrestore(&local->lock, flags);
998}
999
1000#else /* PRISM2_IO_DEBUG */
1001
1002static inline void prism2_io_debug_add(struct net_device *dev, int cmd,
1003 int reg, int value)
1004{
1005}
1006
1007static inline void prism2_io_debug_error(struct net_device *dev, int err)
1008{
1009}
1010
1011#endif /* PRISM2_IO_DEBUG */
1012
1013
1014#ifdef PRISM2_CALLBACK
1015enum {
1016 /* Called when card is enabled */
1017 PRISM2_CALLBACK_ENABLE,
1018
1019 /* Called when card is disabled */
1020 PRISM2_CALLBACK_DISABLE,
1021
1022 /* Called when RX/TX starts/ends */
1023 PRISM2_CALLBACK_RX_START, PRISM2_CALLBACK_RX_END,
1024 PRISM2_CALLBACK_TX_START, PRISM2_CALLBACK_TX_END
1025};
1026void prism2_callback(local_info_t *local, int event);
1027#else /* PRISM2_CALLBACK */
1028#define prism2_callback(d, e) do { } while (0)
1029#endif /* PRISM2_CALLBACK */
1030
1031#endif /* __KERNEL__ */
1032
1033#endif /* HOSTAP_WLAN_H */
diff --git a/drivers/net/wireless/ieee802_11.h b/drivers/net/wireless/ieee802_11.h
deleted file mode 100644
index 53dd5248f9f1..000000000000
--- a/drivers/net/wireless/ieee802_11.h
+++ /dev/null
@@ -1,78 +0,0 @@
1#ifndef _IEEE802_11_H
2#define _IEEE802_11_H
3
4#define IEEE802_11_DATA_LEN 2304
5/* Maximum size for the MA-UNITDATA primitive, 802.11 standard section
6 6.2.1.1.2.
7
8 The figure in section 7.1.2 suggests a body size of up to 2312
9 bytes is allowed, which is a bit confusing, I suspect this
10 represents the 2304 bytes of real data, plus a possible 8 bytes of
11 WEP IV and ICV. (this interpretation suggested by Ramiro Barreiro) */
12
13
14#define IEEE802_11_HLEN 30
15#define IEEE802_11_FRAME_LEN (IEEE802_11_DATA_LEN + IEEE802_11_HLEN)
16
17struct ieee802_11_hdr {
18 u16 frame_ctl;
19 u16 duration_id;
20 u8 addr1[ETH_ALEN];
21 u8 addr2[ETH_ALEN];
22 u8 addr3[ETH_ALEN];
23 u16 seq_ctl;
24 u8 addr4[ETH_ALEN];
25} __attribute__ ((packed));
26
27/* Frame control field constants */
28#define IEEE802_11_FCTL_VERS 0x0002
29#define IEEE802_11_FCTL_FTYPE 0x000c
30#define IEEE802_11_FCTL_STYPE 0x00f0
31#define IEEE802_11_FCTL_TODS 0x0100
32#define IEEE802_11_FCTL_FROMDS 0x0200
33#define IEEE802_11_FCTL_MOREFRAGS 0x0400
34#define IEEE802_11_FCTL_RETRY 0x0800
35#define IEEE802_11_FCTL_PM 0x1000
36#define IEEE802_11_FCTL_MOREDATA 0x2000
37#define IEEE802_11_FCTL_WEP 0x4000
38#define IEEE802_11_FCTL_ORDER 0x8000
39
40#define IEEE802_11_FTYPE_MGMT 0x0000
41#define IEEE802_11_FTYPE_CTL 0x0004
42#define IEEE802_11_FTYPE_DATA 0x0008
43
44/* management */
45#define IEEE802_11_STYPE_ASSOC_REQ 0x0000
46#define IEEE802_11_STYPE_ASSOC_RESP 0x0010
47#define IEEE802_11_STYPE_REASSOC_REQ 0x0020
48#define IEEE802_11_STYPE_REASSOC_RESP 0x0030
49#define IEEE802_11_STYPE_PROBE_REQ 0x0040
50#define IEEE802_11_STYPE_PROBE_RESP 0x0050
51#define IEEE802_11_STYPE_BEACON 0x0080
52#define IEEE802_11_STYPE_ATIM 0x0090
53#define IEEE802_11_STYPE_DISASSOC 0x00A0
54#define IEEE802_11_STYPE_AUTH 0x00B0
55#define IEEE802_11_STYPE_DEAUTH 0x00C0
56
57/* control */
58#define IEEE802_11_STYPE_PSPOLL 0x00A0
59#define IEEE802_11_STYPE_RTS 0x00B0
60#define IEEE802_11_STYPE_CTS 0x00C0
61#define IEEE802_11_STYPE_ACK 0x00D0
62#define IEEE802_11_STYPE_CFEND 0x00E0
63#define IEEE802_11_STYPE_CFENDACK 0x00F0
64
65/* data */
66#define IEEE802_11_STYPE_DATA 0x0000
67#define IEEE802_11_STYPE_DATA_CFACK 0x0010
68#define IEEE802_11_STYPE_DATA_CFPOLL 0x0020
69#define IEEE802_11_STYPE_DATA_CFACKPOLL 0x0030
70#define IEEE802_11_STYPE_NULLFUNC 0x0040
71#define IEEE802_11_STYPE_CFACK 0x0050
72#define IEEE802_11_STYPE_CFPOLL 0x0060
73#define IEEE802_11_STYPE_CFACKPOLL 0x0070
74
75#define IEEE802_11_SCTL_FRAG 0x000F
76#define IEEE802_11_SCTL_SEQ 0xFFF0
77
78#endif /* _IEEE802_11_H */
diff --git a/drivers/net/wireless/ipw2100.c b/drivers/net/wireless/ipw2100.c
new file mode 100644
index 000000000000..a47fce4beadf
--- /dev/null
+++ b/drivers/net/wireless/ipw2100.c
@@ -0,0 +1,8679 @@
1/******************************************************************************
2
3 Copyright(c) 2003 - 2005 Intel Corporation. All rights reserved.
4
5 This program is free software; you can redistribute it and/or modify it
6 under the terms of version 2 of the GNU General Public License as
7 published by the Free Software Foundation.
8
9 This program is distributed in the hope that it will be useful, but WITHOUT
10 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11 FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
12 more details.
13
14 You should have received a copy of the GNU General Public License along with
15 this program; if not, write to the Free Software Foundation, Inc., 59
16 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
17
18 The full GNU General Public License is included in this distribution in the
19 file called LICENSE.
20
21 Contact Information:
22 James P. Ketrenos <ipw2100-admin@linux.intel.com>
23 Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497
24
25 Portions of this file are based on the sample_* files provided by Wireless
26 Extensions 0.26 package and copyright (c) 1997-2003 Jean Tourrilhes
27 <jt@hpl.hp.com>
28
29 Portions of this file are based on the Host AP project,
30 Copyright (c) 2001-2002, SSH Communications Security Corp and Jouni Malinen
31 <jkmaline@cc.hut.fi>
32 Copyright (c) 2002-2003, Jouni Malinen <jkmaline@cc.hut.fi>
33
34 Portions of ipw2100_mod_firmware_load, ipw2100_do_mod_firmware_load, and
35 ipw2100_fw_load are loosely based on drivers/sound/sound_firmware.c
36 available in the 2.4.25 kernel sources, and are copyright (c) Alan Cox
37
38******************************************************************************/
39/*
40
41 Initial driver on which this is based was developed by Janusz Gorycki,
42 Maciej Urbaniak, and Maciej Sosnowski.
43
44 Promiscuous mode support added by Jacek Wysoczynski and Maciej Urbaniak.
45
46Theory of Operation
47
48Tx - Commands and Data
49
50Firmware and host share a circular queue of Transmit Buffer Descriptors (TBDs)
51Each TBD contains a pointer to the physical (dma_addr_t) address of data being
52sent to the firmware as well as the length of the data.
53
54The host writes to the TBD queue at the WRITE index. The WRITE index points
55to the _next_ packet to be written and is advanced when after the TBD has been
56filled.
57
58The firmware pulls from the TBD queue at the READ index. The READ index points
59to the currently being read entry, and is advanced once the firmware is
60done with a packet.
61
62When data is sent to the firmware, the first TBD is used to indicate to the
63firmware if a Command or Data is being sent. If it is Command, all of the
64command information is contained within the physical address referred to by the
65TBD. If it is Data, the first TBD indicates the type of data packet, number
66of fragments, etc. The next TBD then referrs to the actual packet location.
67
68The Tx flow cycle is as follows:
69
701) ipw2100_tx() is called by kernel with SKB to transmit
712) Packet is move from the tx_free_list and appended to the transmit pending
72 list (tx_pend_list)
733) work is scheduled to move pending packets into the shared circular queue.
744) when placing packet in the circular queue, the incoming SKB is DMA mapped
75 to a physical address. That address is entered into a TBD. Two TBDs are
76 filled out. The first indicating a data packet, the second referring to the
77 actual payload data.
785) the packet is removed from tx_pend_list and placed on the end of the
79 firmware pending list (fw_pend_list)
806) firmware is notified that the WRITE index has
817) Once the firmware has processed the TBD, INTA is triggered.
828) For each Tx interrupt received from the firmware, the READ index is checked
83 to see which TBDs are done being processed.
849) For each TBD that has been processed, the ISR pulls the oldest packet
85 from the fw_pend_list.
8610)The packet structure contained in the fw_pend_list is then used
87 to unmap the DMA address and to free the SKB originally passed to the driver
88 from the kernel.
8911)The packet structure is placed onto the tx_free_list
90
91The above steps are the same for commands, only the msg_free_list/msg_pend_list
92are used instead of tx_free_list/tx_pend_list
93
94...
95
96Critical Sections / Locking :
97
98There are two locks utilized. The first is the low level lock (priv->low_lock)
99that protects the following:
100
101- Access to the Tx/Rx queue lists via priv->low_lock. The lists are as follows:
102
103 tx_free_list : Holds pre-allocated Tx buffers.
104 TAIL modified in __ipw2100_tx_process()
105 HEAD modified in ipw2100_tx()
106
107 tx_pend_list : Holds used Tx buffers waiting to go into the TBD ring
108 TAIL modified ipw2100_tx()
109 HEAD modified by ipw2100_tx_send_data()
110
111 msg_free_list : Holds pre-allocated Msg (Command) buffers
112 TAIL modified in __ipw2100_tx_process()
113 HEAD modified in ipw2100_hw_send_command()
114
115 msg_pend_list : Holds used Msg buffers waiting to go into the TBD ring
116 TAIL modified in ipw2100_hw_send_command()
117 HEAD modified in ipw2100_tx_send_commands()
118
119 The flow of data on the TX side is as follows:
120
121 MSG_FREE_LIST + COMMAND => MSG_PEND_LIST => TBD => MSG_FREE_LIST
122 TX_FREE_LIST + DATA => TX_PEND_LIST => TBD => TX_FREE_LIST
123
124 The methods that work on the TBD ring are protected via priv->low_lock.
125
126- The internal data state of the device itself
127- Access to the firmware read/write indexes for the BD queues
128 and associated logic
129
130All external entry functions are locked with the priv->action_lock to ensure
131that only one external action is invoked at a time.
132
133
134*/
135
136#include <linux/compiler.h>
137#include <linux/config.h>
138#include <linux/errno.h>
139#include <linux/if_arp.h>
140#include <linux/in6.h>
141#include <linux/in.h>
142#include <linux/ip.h>
143#include <linux/kernel.h>
144#include <linux/kmod.h>
145#include <linux/module.h>
146#include <linux/netdevice.h>
147#include <linux/ethtool.h>
148#include <linux/pci.h>
149#include <linux/dma-mapping.h>
150#include <linux/proc_fs.h>
151#include <linux/skbuff.h>
152#include <asm/uaccess.h>
153#include <asm/io.h>
154#define __KERNEL_SYSCALLS__
155#include <linux/fs.h>
156#include <linux/mm.h>
157#include <linux/slab.h>
158#include <linux/unistd.h>
159#include <linux/stringify.h>
160#include <linux/tcp.h>
161#include <linux/types.h>
162#include <linux/version.h>
163#include <linux/time.h>
164#include <linux/firmware.h>
165#include <linux/acpi.h>
166#include <linux/ctype.h>
167
168#include "ipw2100.h"
169
170#define IPW2100_VERSION "1.1.0"
171
172#define DRV_NAME "ipw2100"
173#define DRV_VERSION IPW2100_VERSION
174#define DRV_DESCRIPTION "Intel(R) PRO/Wireless 2100 Network Driver"
175#define DRV_COPYRIGHT "Copyright(c) 2003-2004 Intel Corporation"
176
177
178/* Debugging stuff */
179#ifdef CONFIG_IPW_DEBUG
180#define CONFIG_IPW2100_RX_DEBUG /* Reception debugging */
181#endif
182
183MODULE_DESCRIPTION(DRV_DESCRIPTION);
184MODULE_VERSION(DRV_VERSION);
185MODULE_AUTHOR(DRV_COPYRIGHT);
186MODULE_LICENSE("GPL");
187
188static int debug = 0;
189static int mode = 0;
190static int channel = 0;
191static int associate = 1;
192static int disable = 0;
193#ifdef CONFIG_PM
194static struct ipw2100_fw ipw2100_firmware;
195#endif
196
197#include <linux/moduleparam.h>
198module_param(debug, int, 0444);
199module_param(mode, int, 0444);
200module_param(channel, int, 0444);
201module_param(associate, int, 0444);
202module_param(disable, int, 0444);
203
204MODULE_PARM_DESC(debug, "debug level");
205MODULE_PARM_DESC(mode, "network mode (0=BSS,1=IBSS,2=Monitor)");
206MODULE_PARM_DESC(channel, "channel");
207MODULE_PARM_DESC(associate, "auto associate when scanning (default on)");
208MODULE_PARM_DESC(disable, "manually disable the radio (default 0 [radio on])");
209
210static u32 ipw2100_debug_level = IPW_DL_NONE;
211
212#ifdef CONFIG_IPW_DEBUG
213#define IPW_DEBUG(level, message...) \
214do { \
215 if (ipw2100_debug_level & (level)) { \
216 printk(KERN_DEBUG "ipw2100: %c %s ", \
217 in_interrupt() ? 'I' : 'U', __FUNCTION__); \
218 printk(message); \
219 } \
220} while (0)
221#else
222#define IPW_DEBUG(level, message...) do {} while (0)
223#endif /* CONFIG_IPW_DEBUG */
224
225#ifdef CONFIG_IPW_DEBUG
226static const char *command_types[] = {
227 "undefined",
228 "unused", /* HOST_ATTENTION */
229 "HOST_COMPLETE",
230 "unused", /* SLEEP */
231 "unused", /* HOST_POWER_DOWN */
232 "unused",
233 "SYSTEM_CONFIG",
234 "unused", /* SET_IMR */
235 "SSID",
236 "MANDATORY_BSSID",
237 "AUTHENTICATION_TYPE",
238 "ADAPTER_ADDRESS",
239 "PORT_TYPE",
240 "INTERNATIONAL_MODE",
241 "CHANNEL",
242 "RTS_THRESHOLD",
243 "FRAG_THRESHOLD",
244 "POWER_MODE",
245 "TX_RATES",
246 "BASIC_TX_RATES",
247 "WEP_KEY_INFO",
248 "unused",
249 "unused",
250 "unused",
251 "unused",
252 "WEP_KEY_INDEX",
253 "WEP_FLAGS",
254 "ADD_MULTICAST",
255 "CLEAR_ALL_MULTICAST",
256 "BEACON_INTERVAL",
257 "ATIM_WINDOW",
258 "CLEAR_STATISTICS",
259 "undefined",
260 "undefined",
261 "undefined",
262 "undefined",
263 "TX_POWER_INDEX",
264 "undefined",
265 "undefined",
266 "undefined",
267 "undefined",
268 "undefined",
269 "undefined",
270 "BROADCAST_SCAN",
271 "CARD_DISABLE",
272 "PREFERRED_BSSID",
273 "SET_SCAN_OPTIONS",
274 "SCAN_DWELL_TIME",
275 "SWEEP_TABLE",
276 "AP_OR_STATION_TABLE",
277 "GROUP_ORDINALS",
278 "SHORT_RETRY_LIMIT",
279 "LONG_RETRY_LIMIT",
280 "unused", /* SAVE_CALIBRATION */
281 "unused", /* RESTORE_CALIBRATION */
282 "undefined",
283 "undefined",
284 "undefined",
285 "HOST_PRE_POWER_DOWN",
286 "unused", /* HOST_INTERRUPT_COALESCING */
287 "undefined",
288 "CARD_DISABLE_PHY_OFF",
289 "MSDU_TX_RATES"
290 "undefined",
291 "undefined",
292 "SET_STATION_STAT_BITS",
293 "CLEAR_STATIONS_STAT_BITS",
294 "LEAP_ROGUE_MODE",
295 "SET_SECURITY_INFORMATION",
296 "DISASSOCIATION_BSSID",
297 "SET_WPA_ASS_IE"
298};
299#endif
300
301
302/* Pre-decl until we get the code solid and then we can clean it up */
303static void ipw2100_tx_send_commands(struct ipw2100_priv *priv);
304static void ipw2100_tx_send_data(struct ipw2100_priv *priv);
305static int ipw2100_adapter_setup(struct ipw2100_priv *priv);
306
307static void ipw2100_queues_initialize(struct ipw2100_priv *priv);
308static void ipw2100_queues_free(struct ipw2100_priv *priv);
309static int ipw2100_queues_allocate(struct ipw2100_priv *priv);
310
311static int ipw2100_fw_download(struct ipw2100_priv *priv,
312 struct ipw2100_fw *fw);
313static int ipw2100_get_firmware(struct ipw2100_priv *priv,
314 struct ipw2100_fw *fw);
315static int ipw2100_get_fwversion(struct ipw2100_priv *priv, char *buf,
316 size_t max);
317static int ipw2100_get_ucodeversion(struct ipw2100_priv *priv, char *buf,
318 size_t max);
319static void ipw2100_release_firmware(struct ipw2100_priv *priv,
320 struct ipw2100_fw *fw);
321static int ipw2100_ucode_download(struct ipw2100_priv *priv,
322 struct ipw2100_fw *fw);
323static void ipw2100_wx_event_work(struct ipw2100_priv *priv);
324static struct iw_statistics *ipw2100_wx_wireless_stats(struct net_device * dev);
325static struct iw_handler_def ipw2100_wx_handler_def;
326
327
328static inline void read_register(struct net_device *dev, u32 reg, u32 *val)
329{
330 *val = readl((void *)(dev->base_addr + reg));
331 IPW_DEBUG_IO("r: 0x%08X => 0x%08X\n", reg, *val);
332}
333
334static inline void write_register(struct net_device *dev, u32 reg, u32 val)
335{
336 writel(val, (void *)(dev->base_addr + reg));
337 IPW_DEBUG_IO("w: 0x%08X <= 0x%08X\n", reg, val);
338}
339
340static inline void read_register_word(struct net_device *dev, u32 reg, u16 *val)
341{
342 *val = readw((void *)(dev->base_addr + reg));
343 IPW_DEBUG_IO("r: 0x%08X => %04X\n", reg, *val);
344}
345
346static inline void read_register_byte(struct net_device *dev, u32 reg, u8 *val)
347{
348 *val = readb((void *)(dev->base_addr + reg));
349 IPW_DEBUG_IO("r: 0x%08X => %02X\n", reg, *val);
350}
351
352static inline void write_register_word(struct net_device *dev, u32 reg, u16 val)
353{
354 writew(val, (void *)(dev->base_addr + reg));
355 IPW_DEBUG_IO("w: 0x%08X <= %04X\n", reg, val);
356}
357
358
359static inline void write_register_byte(struct net_device *dev, u32 reg, u8 val)
360{
361 writeb(val, (void *)(dev->base_addr + reg));
362 IPW_DEBUG_IO("w: 0x%08X =< %02X\n", reg, val);
363}
364
365static inline void read_nic_dword(struct net_device *dev, u32 addr, u32 *val)
366{
367 write_register(dev, IPW_REG_INDIRECT_ACCESS_ADDRESS,
368 addr & IPW_REG_INDIRECT_ADDR_MASK);
369 read_register(dev, IPW_REG_INDIRECT_ACCESS_DATA, val);
370}
371
372static inline void write_nic_dword(struct net_device *dev, u32 addr, u32 val)
373{
374 write_register(dev, IPW_REG_INDIRECT_ACCESS_ADDRESS,
375 addr & IPW_REG_INDIRECT_ADDR_MASK);
376 write_register(dev, IPW_REG_INDIRECT_ACCESS_DATA, val);
377}
378
379static inline void read_nic_word(struct net_device *dev, u32 addr, u16 *val)
380{
381 write_register(dev, IPW_REG_INDIRECT_ACCESS_ADDRESS,
382 addr & IPW_REG_INDIRECT_ADDR_MASK);
383 read_register_word(dev, IPW_REG_INDIRECT_ACCESS_DATA, val);
384}
385
386static inline void write_nic_word(struct net_device *dev, u32 addr, u16 val)
387{
388 write_register(dev, IPW_REG_INDIRECT_ACCESS_ADDRESS,
389 addr & IPW_REG_INDIRECT_ADDR_MASK);
390 write_register_word(dev, IPW_REG_INDIRECT_ACCESS_DATA, val);
391}
392
393static inline void read_nic_byte(struct net_device *dev, u32 addr, u8 *val)
394{
395 write_register(dev, IPW_REG_INDIRECT_ACCESS_ADDRESS,
396 addr & IPW_REG_INDIRECT_ADDR_MASK);
397 read_register_byte(dev, IPW_REG_INDIRECT_ACCESS_DATA, val);
398}
399
400static inline void write_nic_byte(struct net_device *dev, u32 addr, u8 val)
401{
402 write_register(dev, IPW_REG_INDIRECT_ACCESS_ADDRESS,
403 addr & IPW_REG_INDIRECT_ADDR_MASK);
404 write_register_byte(dev, IPW_REG_INDIRECT_ACCESS_DATA, val);
405}
406
407static inline void write_nic_auto_inc_address(struct net_device *dev, u32 addr)
408{
409 write_register(dev, IPW_REG_AUTOINCREMENT_ADDRESS,
410 addr & IPW_REG_INDIRECT_ADDR_MASK);
411}
412
413static inline void write_nic_dword_auto_inc(struct net_device *dev, u32 val)
414{
415 write_register(dev, IPW_REG_AUTOINCREMENT_DATA, val);
416}
417
418static inline void write_nic_memory(struct net_device *dev, u32 addr, u32 len,
419 const u8 *buf)
420{
421 u32 aligned_addr;
422 u32 aligned_len;
423 u32 dif_len;
424 u32 i;
425
426 /* read first nibble byte by byte */
427 aligned_addr = addr & (~0x3);
428 dif_len = addr - aligned_addr;
429 if (dif_len) {
430 /* Start reading at aligned_addr + dif_len */
431 write_register(dev, IPW_REG_INDIRECT_ACCESS_ADDRESS,
432 aligned_addr);
433 for (i = dif_len; i < 4; i++, buf++)
434 write_register_byte(
435 dev, IPW_REG_INDIRECT_ACCESS_DATA + i,
436 *buf);
437
438 len -= dif_len;
439 aligned_addr += 4;
440 }
441
442 /* read DWs through autoincrement registers */
443 write_register(dev, IPW_REG_AUTOINCREMENT_ADDRESS,
444 aligned_addr);
445 aligned_len = len & (~0x3);
446 for (i = 0; i < aligned_len; i += 4, buf += 4, aligned_addr += 4)
447 write_register(
448 dev, IPW_REG_AUTOINCREMENT_DATA, *(u32 *)buf);
449
450 /* copy the last nibble */
451 dif_len = len - aligned_len;
452 write_register(dev, IPW_REG_INDIRECT_ACCESS_ADDRESS, aligned_addr);
453 for (i = 0; i < dif_len; i++, buf++)
454 write_register_byte(
455 dev, IPW_REG_INDIRECT_ACCESS_DATA + i, *buf);
456}
457
458static inline void read_nic_memory(struct net_device *dev, u32 addr, u32 len,
459 u8 *buf)
460{
461 u32 aligned_addr;
462 u32 aligned_len;
463 u32 dif_len;
464 u32 i;
465
466 /* read first nibble byte by byte */
467 aligned_addr = addr & (~0x3);
468 dif_len = addr - aligned_addr;
469 if (dif_len) {
470 /* Start reading at aligned_addr + dif_len */
471 write_register(dev, IPW_REG_INDIRECT_ACCESS_ADDRESS,
472 aligned_addr);
473 for (i = dif_len; i < 4; i++, buf++)
474 read_register_byte(
475 dev, IPW_REG_INDIRECT_ACCESS_DATA + i, buf);
476
477 len -= dif_len;
478 aligned_addr += 4;
479 }
480
481 /* read DWs through autoincrement registers */
482 write_register(dev, IPW_REG_AUTOINCREMENT_ADDRESS,
483 aligned_addr);
484 aligned_len = len & (~0x3);
485 for (i = 0; i < aligned_len; i += 4, buf += 4, aligned_addr += 4)
486 read_register(dev, IPW_REG_AUTOINCREMENT_DATA,
487 (u32 *)buf);
488
489 /* copy the last nibble */
490 dif_len = len - aligned_len;
491 write_register(dev, IPW_REG_INDIRECT_ACCESS_ADDRESS,
492 aligned_addr);
493 for (i = 0; i < dif_len; i++, buf++)
494 read_register_byte(dev, IPW_REG_INDIRECT_ACCESS_DATA +
495 i, buf);
496}
497
498static inline int ipw2100_hw_is_adapter_in_system(struct net_device *dev)
499{
500 return (dev->base_addr &&
501 (readl((void *)(dev->base_addr + IPW_REG_DOA_DEBUG_AREA_START))
502 == IPW_DATA_DOA_DEBUG_VALUE));
503}
504
505static int ipw2100_get_ordinal(struct ipw2100_priv *priv, u32 ord,
506 void *val, u32 *len)
507{
508 struct ipw2100_ordinals *ordinals = &priv->ordinals;
509 u32 addr;
510 u32 field_info;
511 u16 field_len;
512 u16 field_count;
513 u32 total_length;
514
515 if (ordinals->table1_addr == 0) {
516 printk(KERN_WARNING DRV_NAME ": attempt to use fw ordinals "
517 "before they have been loaded.\n");
518 return -EINVAL;
519 }
520
521 if (IS_ORDINAL_TABLE_ONE(ordinals, ord)) {
522 if (*len < IPW_ORD_TAB_1_ENTRY_SIZE) {
523 *len = IPW_ORD_TAB_1_ENTRY_SIZE;
524
525 printk(KERN_WARNING DRV_NAME
526 ": ordinal buffer length too small, need %zd\n",
527 IPW_ORD_TAB_1_ENTRY_SIZE);
528
529 return -EINVAL;
530 }
531
532 read_nic_dword(priv->net_dev, ordinals->table1_addr + (ord << 2),
533 &addr);
534 read_nic_dword(priv->net_dev, addr, val);
535
536 *len = IPW_ORD_TAB_1_ENTRY_SIZE;
537
538 return 0;
539 }
540
541 if (IS_ORDINAL_TABLE_TWO(ordinals, ord)) {
542
543 ord -= IPW_START_ORD_TAB_2;
544
545 /* get the address of statistic */
546 read_nic_dword(priv->net_dev, ordinals->table2_addr + (ord << 3),
547 &addr);
548
549 /* get the second DW of statistics ;
550 * two 16-bit words - first is length, second is count */
551 read_nic_dword(priv->net_dev,
552 ordinals->table2_addr + (ord << 3) + sizeof(u32),
553 &field_info);
554
555 /* get each entry length */
556 field_len = *((u16 *)&field_info);
557
558 /* get number of entries */
559 field_count = *(((u16 *)&field_info) + 1);
560
561 /* abort if no enought memory */
562 total_length = field_len * field_count;
563 if (total_length > *len) {
564 *len = total_length;
565 return -EINVAL;
566 }
567
568 *len = total_length;
569 if (!total_length)
570 return 0;
571
572 /* read the ordinal data from the SRAM */
573 read_nic_memory(priv->net_dev, addr, total_length, val);
574
575 return 0;
576 }
577
578 printk(KERN_WARNING DRV_NAME ": ordinal %d neither in table 1 nor "
579 "in table 2\n", ord);
580
581 return -EINVAL;
582}
583
584static int ipw2100_set_ordinal(struct ipw2100_priv *priv, u32 ord, u32 *val,
585 u32 *len)
586{
587 struct ipw2100_ordinals *ordinals = &priv->ordinals;
588 u32 addr;
589
590 if (IS_ORDINAL_TABLE_ONE(ordinals, ord)) {
591 if (*len != IPW_ORD_TAB_1_ENTRY_SIZE) {
592 *len = IPW_ORD_TAB_1_ENTRY_SIZE;
593 IPW_DEBUG_INFO("wrong size\n");
594 return -EINVAL;
595 }
596
597 read_nic_dword(priv->net_dev, ordinals->table1_addr + (ord << 2),
598 &addr);
599
600 write_nic_dword(priv->net_dev, addr, *val);
601
602 *len = IPW_ORD_TAB_1_ENTRY_SIZE;
603
604 return 0;
605 }
606
607 IPW_DEBUG_INFO("wrong table\n");
608 if (IS_ORDINAL_TABLE_TWO(ordinals, ord))
609 return -EINVAL;
610
611 return -EINVAL;
612}
613
614static char *snprint_line(char *buf, size_t count,
615 const u8 *data, u32 len, u32 ofs)
616{
617 int out, i, j, l;
618 char c;
619
620 out = snprintf(buf, count, "%08X", ofs);
621
622 for (l = 0, i = 0; i < 2; i++) {
623 out += snprintf(buf + out, count - out, " ");
624 for (j = 0; j < 8 && l < len; j++, l++)
625 out += snprintf(buf + out, count - out, "%02X ",
626 data[(i * 8 + j)]);
627 for (; j < 8; j++)
628 out += snprintf(buf + out, count - out, " ");
629 }
630
631 out += snprintf(buf + out, count - out, " ");
632 for (l = 0, i = 0; i < 2; i++) {
633 out += snprintf(buf + out, count - out, " ");
634 for (j = 0; j < 8 && l < len; j++, l++) {
635 c = data[(i * 8 + j)];
636 if (!isascii(c) || !isprint(c))
637 c = '.';
638
639 out += snprintf(buf + out, count - out, "%c", c);
640 }
641
642 for (; j < 8; j++)
643 out += snprintf(buf + out, count - out, " ");
644 }
645
646 return buf;
647}
648
649static void printk_buf(int level, const u8 *data, u32 len)
650{
651 char line[81];
652 u32 ofs = 0;
653 if (!(ipw2100_debug_level & level))
654 return;
655
656 while (len) {
657 printk(KERN_DEBUG "%s\n",
658 snprint_line(line, sizeof(line), &data[ofs],
659 min(len, 16U), ofs));
660 ofs += 16;
661 len -= min(len, 16U);
662 }
663}
664
665
666
667#define MAX_RESET_BACKOFF 10
668
669static inline void schedule_reset(struct ipw2100_priv *priv)
670{
671 unsigned long now = get_seconds();
672
673 /* If we haven't received a reset request within the backoff period,
674 * then we can reset the backoff interval so this reset occurs
675 * immediately */
676 if (priv->reset_backoff &&
677 (now - priv->last_reset > priv->reset_backoff))
678 priv->reset_backoff = 0;
679
680 priv->last_reset = get_seconds();
681
682 if (!(priv->status & STATUS_RESET_PENDING)) {
683 IPW_DEBUG_INFO("%s: Scheduling firmware restart (%ds).\n",
684 priv->net_dev->name, priv->reset_backoff);
685 netif_carrier_off(priv->net_dev);
686 netif_stop_queue(priv->net_dev);
687 priv->status |= STATUS_RESET_PENDING;
688 if (priv->reset_backoff)
689 queue_delayed_work(priv->workqueue, &priv->reset_work,
690 priv->reset_backoff * HZ);
691 else
692 queue_work(priv->workqueue, &priv->reset_work);
693
694 if (priv->reset_backoff < MAX_RESET_BACKOFF)
695 priv->reset_backoff++;
696
697 wake_up_interruptible(&priv->wait_command_queue);
698 } else
699 IPW_DEBUG_INFO("%s: Firmware restart already in progress.\n",
700 priv->net_dev->name);
701
702}
703
704#define HOST_COMPLETE_TIMEOUT (2 * HZ)
705static int ipw2100_hw_send_command(struct ipw2100_priv *priv,
706 struct host_command * cmd)
707{
708 struct list_head *element;
709 struct ipw2100_tx_packet *packet;
710 unsigned long flags;
711 int err = 0;
712
713 IPW_DEBUG_HC("Sending %s command (#%d), %d bytes\n",
714 command_types[cmd->host_command], cmd->host_command,
715 cmd->host_command_length);
716 printk_buf(IPW_DL_HC, (u8*)cmd->host_command_parameters,
717 cmd->host_command_length);
718
719 spin_lock_irqsave(&priv->low_lock, flags);
720
721 if (priv->fatal_error) {
722 IPW_DEBUG_INFO("Attempt to send command while hardware in fatal error condition.\n");
723 err = -EIO;
724 goto fail_unlock;
725 }
726
727 if (!(priv->status & STATUS_RUNNING)) {
728 IPW_DEBUG_INFO("Attempt to send command while hardware is not running.\n");
729 err = -EIO;
730 goto fail_unlock;
731 }
732
733 if (priv->status & STATUS_CMD_ACTIVE) {
734 IPW_DEBUG_INFO("Attempt to send command while another command is pending.\n");
735 err = -EBUSY;
736 goto fail_unlock;
737 }
738
739 if (list_empty(&priv->msg_free_list)) {
740 IPW_DEBUG_INFO("no available msg buffers\n");
741 goto fail_unlock;
742 }
743
744 priv->status |= STATUS_CMD_ACTIVE;
745 priv->messages_sent++;
746
747 element = priv->msg_free_list.next;
748
749 packet = list_entry(element, struct ipw2100_tx_packet, list);
750 packet->jiffy_start = jiffies;
751
752 /* initialize the firmware command packet */
753 packet->info.c_struct.cmd->host_command_reg = cmd->host_command;
754 packet->info.c_struct.cmd->host_command_reg1 = cmd->host_command1;
755 packet->info.c_struct.cmd->host_command_len_reg = cmd->host_command_length;
756 packet->info.c_struct.cmd->sequence = cmd->host_command_sequence;
757
758 memcpy(packet->info.c_struct.cmd->host_command_params_reg,
759 cmd->host_command_parameters,
760 sizeof(packet->info.c_struct.cmd->host_command_params_reg));
761
762 list_del(element);
763 DEC_STAT(&priv->msg_free_stat);
764
765 list_add_tail(element, &priv->msg_pend_list);
766 INC_STAT(&priv->msg_pend_stat);
767
768 ipw2100_tx_send_commands(priv);
769 ipw2100_tx_send_data(priv);
770
771 spin_unlock_irqrestore(&priv->low_lock, flags);
772
773 /*
774 * We must wait for this command to complete before another
775 * command can be sent... but if we wait more than 3 seconds
776 * then there is a problem.
777 */
778
779 err = wait_event_interruptible_timeout(
780 priv->wait_command_queue, !(priv->status & STATUS_CMD_ACTIVE),
781 HOST_COMPLETE_TIMEOUT);
782
783 if (err == 0) {
784 IPW_DEBUG_INFO("Command completion failed out after %dms.\n",
785 HOST_COMPLETE_TIMEOUT / (HZ / 100));
786 priv->fatal_error = IPW2100_ERR_MSG_TIMEOUT;
787 priv->status &= ~STATUS_CMD_ACTIVE;
788 schedule_reset(priv);
789 return -EIO;
790 }
791
792 if (priv->fatal_error) {
793 printk(KERN_WARNING DRV_NAME ": %s: firmware fatal error\n",
794 priv->net_dev->name);
795 return -EIO;
796 }
797
798 /* !!!!! HACK TEST !!!!!
799 * When lots of debug trace statements are enabled, the driver
800 * doesn't seem to have as many firmware restart cycles...
801 *
802 * As a test, we're sticking in a 1/100s delay here */
803 set_current_state(TASK_UNINTERRUPTIBLE);
804 schedule_timeout(HZ / 100);
805
806 return 0;
807
808 fail_unlock:
809 spin_unlock_irqrestore(&priv->low_lock, flags);
810
811 return err;
812}
813
814
815/*
816 * Verify the values and data access of the hardware
817 * No locks needed or used. No functions called.
818 */
819static int ipw2100_verify(struct ipw2100_priv *priv)
820{
821 u32 data1, data2;
822 u32 address;
823
824 u32 val1 = 0x76543210;
825 u32 val2 = 0xFEDCBA98;
826
827 /* Domain 0 check - all values should be DOA_DEBUG */
828 for (address = IPW_REG_DOA_DEBUG_AREA_START;
829 address < IPW_REG_DOA_DEBUG_AREA_END;
830 address += sizeof(u32)) {
831 read_register(priv->net_dev, address, &data1);
832 if (data1 != IPW_DATA_DOA_DEBUG_VALUE)
833 return -EIO;
834 }
835
836 /* Domain 1 check - use arbitrary read/write compare */
837 for (address = 0; address < 5; address++) {
838 /* The memory area is not used now */
839 write_register(priv->net_dev, IPW_REG_DOMAIN_1_OFFSET + 0x32,
840 val1);
841 write_register(priv->net_dev, IPW_REG_DOMAIN_1_OFFSET + 0x36,
842 val2);
843 read_register(priv->net_dev, IPW_REG_DOMAIN_1_OFFSET + 0x32,
844 &data1);
845 read_register(priv->net_dev, IPW_REG_DOMAIN_1_OFFSET + 0x36,
846 &data2);
847 if (val1 == data1 && val2 == data2)
848 return 0;
849 }
850
851 return -EIO;
852}
853
854/*
855 *
856 * Loop until the CARD_DISABLED bit is the same value as the
857 * supplied parameter
858 *
859 * TODO: See if it would be more efficient to do a wait/wake
860 * cycle and have the completion event trigger the wakeup
861 *
862 */
863#define IPW_CARD_DISABLE_COMPLETE_WAIT 100 // 100 milli
864static int ipw2100_wait_for_card_state(struct ipw2100_priv *priv, int state)
865{
866 int i;
867 u32 card_state;
868 u32 len = sizeof(card_state);
869 int err;
870
871 for (i = 0; i <= IPW_CARD_DISABLE_COMPLETE_WAIT * 1000; i += 50) {
872 err = ipw2100_get_ordinal(priv, IPW_ORD_CARD_DISABLED,
873 &card_state, &len);
874 if (err) {
875 IPW_DEBUG_INFO("Query of CARD_DISABLED ordinal "
876 "failed.\n");
877 return 0;
878 }
879
880 /* We'll break out if either the HW state says it is
881 * in the state we want, or if HOST_COMPLETE command
882 * finishes */
883 if ((card_state == state) ||
884 ((priv->status & STATUS_ENABLED) ?
885 IPW_HW_STATE_ENABLED : IPW_HW_STATE_DISABLED) == state) {
886 if (state == IPW_HW_STATE_ENABLED)
887 priv->status |= STATUS_ENABLED;
888 else
889 priv->status &= ~STATUS_ENABLED;
890
891 return 0;
892 }
893
894 udelay(50);
895 }
896
897 IPW_DEBUG_INFO("ipw2100_wait_for_card_state to %s state timed out\n",
898 state ? "DISABLED" : "ENABLED");
899 return -EIO;
900}
901
902
903/*********************************************************************
904 Procedure : sw_reset_and_clock
905 Purpose : Asserts s/w reset, asserts clock initialization
906 and waits for clock stabilization
907 ********************************************************************/
908static int sw_reset_and_clock(struct ipw2100_priv *priv)
909{
910 int i;
911 u32 r;
912
913 // assert s/w reset
914 write_register(priv->net_dev, IPW_REG_RESET_REG,
915 IPW_AUX_HOST_RESET_REG_SW_RESET);
916
917 // wait for clock stabilization
918 for (i = 0; i < 1000; i++) {
919 udelay(IPW_WAIT_RESET_ARC_COMPLETE_DELAY);
920
921 // check clock ready bit
922 read_register(priv->net_dev, IPW_REG_RESET_REG, &r);
923 if (r & IPW_AUX_HOST_RESET_REG_PRINCETON_RESET)
924 break;
925 }
926
927 if (i == 1000)
928 return -EIO; // TODO: better error value
929
930 /* set "initialization complete" bit to move adapter to
931 * D0 state */
932 write_register(priv->net_dev, IPW_REG_GP_CNTRL,
933 IPW_AUX_HOST_GP_CNTRL_BIT_INIT_DONE);
934
935 /* wait for clock stabilization */
936 for (i = 0; i < 10000; i++) {
937 udelay(IPW_WAIT_CLOCK_STABILIZATION_DELAY * 4);
938
939 /* check clock ready bit */
940 read_register(priv->net_dev, IPW_REG_GP_CNTRL, &r);
941 if (r & IPW_AUX_HOST_GP_CNTRL_BIT_CLOCK_READY)
942 break;
943 }
944
945 if (i == 10000)
946 return -EIO; /* TODO: better error value */
947
948 /* set D0 standby bit */
949 read_register(priv->net_dev, IPW_REG_GP_CNTRL, &r);
950 write_register(priv->net_dev, IPW_REG_GP_CNTRL,
951 r | IPW_AUX_HOST_GP_CNTRL_BIT_HOST_ALLOWS_STANDBY);
952
953 return 0;
954}
955
956/*********************************************************************
957 Procedure : ipw2100_download_firmware
958 Purpose : Initiaze adapter after power on.
959 The sequence is:
960 1. assert s/w reset first!
961 2. awake clocks & wait for clock stabilization
962 3. hold ARC (don't ask me why...)
963 4. load Dino ucode and reset/clock init again
964 5. zero-out shared mem
965 6. download f/w
966 *******************************************************************/
967static int ipw2100_download_firmware(struct ipw2100_priv *priv)
968{
969 u32 address;
970 int err;
971
972#ifndef CONFIG_PM
973 /* Fetch the firmware and microcode */
974 struct ipw2100_fw ipw2100_firmware;
975#endif
976
977 if (priv->fatal_error) {
978 IPW_DEBUG_ERROR("%s: ipw2100_download_firmware called after "
979 "fatal error %d. Interface must be brought down.\n",
980 priv->net_dev->name, priv->fatal_error);
981 return -EINVAL;
982 }
983
984#ifdef CONFIG_PM
985 if (!ipw2100_firmware.version) {
986 err = ipw2100_get_firmware(priv, &ipw2100_firmware);
987 if (err) {
988 IPW_DEBUG_ERROR("%s: ipw2100_get_firmware failed: %d\n",
989 priv->net_dev->name, err);
990 priv->fatal_error = IPW2100_ERR_FW_LOAD;
991 goto fail;
992 }
993 }
994#else
995 err = ipw2100_get_firmware(priv, &ipw2100_firmware);
996 if (err) {
997 IPW_DEBUG_ERROR("%s: ipw2100_get_firmware failed: %d\n",
998 priv->net_dev->name, err);
999 priv->fatal_error = IPW2100_ERR_FW_LOAD;
1000 goto fail;
1001 }
1002#endif
1003 priv->firmware_version = ipw2100_firmware.version;
1004
1005 /* s/w reset and clock stabilization */
1006 err = sw_reset_and_clock(priv);
1007 if (err) {
1008 IPW_DEBUG_ERROR("%s: sw_reset_and_clock failed: %d\n",
1009 priv->net_dev->name, err);
1010 goto fail;
1011 }
1012
1013 err = ipw2100_verify(priv);
1014 if (err) {
1015 IPW_DEBUG_ERROR("%s: ipw2100_verify failed: %d\n",
1016 priv->net_dev->name, err);
1017 goto fail;
1018 }
1019
1020 /* Hold ARC */
1021 write_nic_dword(priv->net_dev,
1022 IPW_INTERNAL_REGISTER_HALT_AND_RESET,
1023 0x80000000);
1024
1025 /* allow ARC to run */
1026 write_register(priv->net_dev, IPW_REG_RESET_REG, 0);
1027
1028 /* load microcode */
1029 err = ipw2100_ucode_download(priv, &ipw2100_firmware);
1030 if (err) {
1031 printk(KERN_ERR DRV_NAME ": %s: Error loading microcode: %d\n",
1032 priv->net_dev->name, err);
1033 goto fail;
1034 }
1035
1036 /* release ARC */
1037 write_nic_dword(priv->net_dev,
1038 IPW_INTERNAL_REGISTER_HALT_AND_RESET,
1039 0x00000000);
1040
1041 /* s/w reset and clock stabilization (again!!!) */
1042 err = sw_reset_and_clock(priv);
1043 if (err) {
1044 printk(KERN_ERR DRV_NAME ": %s: sw_reset_and_clock failed: %d\n",
1045 priv->net_dev->name, err);
1046 goto fail;
1047 }
1048
1049 /* load f/w */
1050 err = ipw2100_fw_download(priv, &ipw2100_firmware);
1051 if (err) {
1052 IPW_DEBUG_ERROR("%s: Error loading firmware: %d\n",
1053 priv->net_dev->name, err);
1054 goto fail;
1055 }
1056
1057#ifndef CONFIG_PM
1058 /*
1059 * When the .resume method of the driver is called, the other
1060 * part of the system, i.e. the ide driver could still stay in
1061 * the suspend stage. This prevents us from loading the firmware
1062 * from the disk. --YZ
1063 */
1064
1065 /* free any storage allocated for firmware image */
1066 ipw2100_release_firmware(priv, &ipw2100_firmware);
1067#endif
1068
1069 /* zero out Domain 1 area indirectly (Si requirement) */
1070 for (address = IPW_HOST_FW_SHARED_AREA0;
1071 address < IPW_HOST_FW_SHARED_AREA0_END; address += 4)
1072 write_nic_dword(priv->net_dev, address, 0);
1073 for (address = IPW_HOST_FW_SHARED_AREA1;
1074 address < IPW_HOST_FW_SHARED_AREA1_END; address += 4)
1075 write_nic_dword(priv->net_dev, address, 0);
1076 for (address = IPW_HOST_FW_SHARED_AREA2;
1077 address < IPW_HOST_FW_SHARED_AREA2_END; address += 4)
1078 write_nic_dword(priv->net_dev, address, 0);
1079 for (address = IPW_HOST_FW_SHARED_AREA3;
1080 address < IPW_HOST_FW_SHARED_AREA3_END; address += 4)
1081 write_nic_dword(priv->net_dev, address, 0);
1082 for (address = IPW_HOST_FW_INTERRUPT_AREA;
1083 address < IPW_HOST_FW_INTERRUPT_AREA_END; address += 4)
1084 write_nic_dword(priv->net_dev, address, 0);
1085
1086 return 0;
1087
1088 fail:
1089 ipw2100_release_firmware(priv, &ipw2100_firmware);
1090 return err;
1091}
1092
1093static inline void ipw2100_enable_interrupts(struct ipw2100_priv *priv)
1094{
1095 if (priv->status & STATUS_INT_ENABLED)
1096 return;
1097 priv->status |= STATUS_INT_ENABLED;
1098 write_register(priv->net_dev, IPW_REG_INTA_MASK, IPW_INTERRUPT_MASK);
1099}
1100
1101static inline void ipw2100_disable_interrupts(struct ipw2100_priv *priv)
1102{
1103 if (!(priv->status & STATUS_INT_ENABLED))
1104 return;
1105 priv->status &= ~STATUS_INT_ENABLED;
1106 write_register(priv->net_dev, IPW_REG_INTA_MASK, 0x0);
1107}
1108
1109
1110static void ipw2100_initialize_ordinals(struct ipw2100_priv *priv)
1111{
1112 struct ipw2100_ordinals *ord = &priv->ordinals;
1113
1114 IPW_DEBUG_INFO("enter\n");
1115
1116 read_register(priv->net_dev, IPW_MEM_HOST_SHARED_ORDINALS_TABLE_1,
1117 &ord->table1_addr);
1118
1119 read_register(priv->net_dev, IPW_MEM_HOST_SHARED_ORDINALS_TABLE_2,
1120 &ord->table2_addr);
1121
1122 read_nic_dword(priv->net_dev, ord->table1_addr, &ord->table1_size);
1123 read_nic_dword(priv->net_dev, ord->table2_addr, &ord->table2_size);
1124
1125 ord->table2_size &= 0x0000FFFF;
1126
1127 IPW_DEBUG_INFO("table 1 size: %d\n", ord->table1_size);
1128 IPW_DEBUG_INFO("table 2 size: %d\n", ord->table2_size);
1129 IPW_DEBUG_INFO("exit\n");
1130}
1131
1132static inline void ipw2100_hw_set_gpio(struct ipw2100_priv *priv)
1133{
1134 u32 reg = 0;
1135 /*
1136 * Set GPIO 3 writable by FW; GPIO 1 writable
1137 * by driver and enable clock
1138 */
1139 reg = (IPW_BIT_GPIO_GPIO3_MASK | IPW_BIT_GPIO_GPIO1_ENABLE |
1140 IPW_BIT_GPIO_LED_OFF);
1141 write_register(priv->net_dev, IPW_REG_GPIO, reg);
1142}
1143
1144static inline int rf_kill_active(struct ipw2100_priv *priv)
1145{
1146#define MAX_RF_KILL_CHECKS 5
1147#define RF_KILL_CHECK_DELAY 40
1148
1149 unsigned short value = 0;
1150 u32 reg = 0;
1151 int i;
1152
1153 if (!(priv->hw_features & HW_FEATURE_RFKILL)) {
1154 priv->status &= ~STATUS_RF_KILL_HW;
1155 return 0;
1156 }
1157
1158 for (i = 0; i < MAX_RF_KILL_CHECKS; i++) {
1159 udelay(RF_KILL_CHECK_DELAY);
1160 read_register(priv->net_dev, IPW_REG_GPIO, &reg);
1161 value = (value << 1) | ((reg & IPW_BIT_GPIO_RF_KILL) ? 0 : 1);
1162 }
1163
1164 if (value == 0)
1165 priv->status |= STATUS_RF_KILL_HW;
1166 else
1167 priv->status &= ~STATUS_RF_KILL_HW;
1168
1169 return (value == 0);
1170}
1171
1172static int ipw2100_get_hw_features(struct ipw2100_priv *priv)
1173{
1174 u32 addr, len;
1175 u32 val;
1176
1177 /*
1178 * EEPROM_SRAM_DB_START_ADDRESS using ordinal in ordinal table 1
1179 */
1180 len = sizeof(addr);
1181 if (ipw2100_get_ordinal(
1182 priv, IPW_ORD_EEPROM_SRAM_DB_BLOCK_START_ADDRESS,
1183 &addr, &len)) {
1184 IPW_DEBUG_INFO("failed querying ordinals at line %d\n",
1185 __LINE__);
1186 return -EIO;
1187 }
1188
1189 IPW_DEBUG_INFO("EEPROM address: %08X\n", addr);
1190
1191 /*
1192 * EEPROM version is the byte at offset 0xfd in firmware
1193 * We read 4 bytes, then shift out the byte we actually want */
1194 read_nic_dword(priv->net_dev, addr + 0xFC, &val);
1195 priv->eeprom_version = (val >> 24) & 0xFF;
1196 IPW_DEBUG_INFO("EEPROM version: %d\n", priv->eeprom_version);
1197
1198 /*
1199 * HW RF Kill enable is bit 0 in byte at offset 0x21 in firmware
1200 *
1201 * notice that the EEPROM bit is reverse polarity, i.e.
1202 * bit = 0 signifies HW RF kill switch is supported
1203 * bit = 1 signifies HW RF kill switch is NOT supported
1204 */
1205 read_nic_dword(priv->net_dev, addr + 0x20, &val);
1206 if (!((val >> 24) & 0x01))
1207 priv->hw_features |= HW_FEATURE_RFKILL;
1208
1209 IPW_DEBUG_INFO("HW RF Kill: %ssupported.\n",
1210 (priv->hw_features & HW_FEATURE_RFKILL) ?
1211 "" : "not ");
1212
1213 return 0;
1214}
1215
1216/*
1217 * Start firmware execution after power on and intialization
1218 * The sequence is:
1219 * 1. Release ARC
1220 * 2. Wait for f/w initialization completes;
1221 */
1222static int ipw2100_start_adapter(struct ipw2100_priv *priv)
1223{
1224 int i;
1225 u32 inta, inta_mask, gpio;
1226
1227 IPW_DEBUG_INFO("enter\n");
1228
1229 if (priv->status & STATUS_RUNNING)
1230 return 0;
1231
1232 /*
1233 * Initialize the hw - drive adapter to DO state by setting
1234 * init_done bit. Wait for clk_ready bit and Download
1235 * fw & dino ucode
1236 */
1237 if (ipw2100_download_firmware(priv)) {
1238 printk(KERN_ERR DRV_NAME ": %s: Failed to power on the adapter.\n",
1239 priv->net_dev->name);
1240 return -EIO;
1241 }
1242
1243 /* Clear the Tx, Rx and Msg queues and the r/w indexes
1244 * in the firmware RBD and TBD ring queue */
1245 ipw2100_queues_initialize(priv);
1246
1247 ipw2100_hw_set_gpio(priv);
1248
1249 /* TODO -- Look at disabling interrupts here to make sure none
1250 * get fired during FW initialization */
1251
1252 /* Release ARC - clear reset bit */
1253 write_register(priv->net_dev, IPW_REG_RESET_REG, 0);
1254
1255 /* wait for f/w intialization complete */
1256 IPW_DEBUG_FW("Waiting for f/w initialization to complete...\n");
1257 i = 5000;
1258 do {
1259 set_current_state(TASK_UNINTERRUPTIBLE);
1260 schedule_timeout(40 * HZ / 1000);
1261 /* Todo... wait for sync command ... */
1262
1263 read_register(priv->net_dev, IPW_REG_INTA, &inta);
1264
1265 /* check "init done" bit */
1266 if (inta & IPW2100_INTA_FW_INIT_DONE) {
1267 /* reset "init done" bit */
1268 write_register(priv->net_dev, IPW_REG_INTA,
1269 IPW2100_INTA_FW_INIT_DONE);
1270 break;
1271 }
1272
1273 /* check error conditions : we check these after the firmware
1274 * check so that if there is an error, the interrupt handler
1275 * will see it and the adapter will be reset */
1276 if (inta &
1277 (IPW2100_INTA_FATAL_ERROR | IPW2100_INTA_PARITY_ERROR)) {
1278 /* clear error conditions */
1279 write_register(priv->net_dev, IPW_REG_INTA,
1280 IPW2100_INTA_FATAL_ERROR |
1281 IPW2100_INTA_PARITY_ERROR);
1282 }
1283 } while (i--);
1284
1285 /* Clear out any pending INTAs since we aren't supposed to have
1286 * interrupts enabled at this point... */
1287 read_register(priv->net_dev, IPW_REG_INTA, &inta);
1288 read_register(priv->net_dev, IPW_REG_INTA_MASK, &inta_mask);
1289 inta &= IPW_INTERRUPT_MASK;
1290 /* Clear out any pending interrupts */
1291 if (inta & inta_mask)
1292 write_register(priv->net_dev, IPW_REG_INTA, inta);
1293
1294 IPW_DEBUG_FW("f/w initialization complete: %s\n",
1295 i ? "SUCCESS" : "FAILED");
1296
1297 if (!i) {
1298 printk(KERN_WARNING DRV_NAME ": %s: Firmware did not initialize.\n",
1299 priv->net_dev->name);
1300 return -EIO;
1301 }
1302
1303 /* allow firmware to write to GPIO1 & GPIO3 */
1304 read_register(priv->net_dev, IPW_REG_GPIO, &gpio);
1305
1306 gpio |= (IPW_BIT_GPIO_GPIO1_MASK | IPW_BIT_GPIO_GPIO3_MASK);
1307
1308 write_register(priv->net_dev, IPW_REG_GPIO, gpio);
1309
1310 /* Ready to receive commands */
1311 priv->status |= STATUS_RUNNING;
1312
1313 /* The adapter has been reset; we are not associated */
1314 priv->status &= ~(STATUS_ASSOCIATING | STATUS_ASSOCIATED);
1315
1316 IPW_DEBUG_INFO("exit\n");
1317
1318 return 0;
1319}
1320
1321static inline void ipw2100_reset_fatalerror(struct ipw2100_priv *priv)
1322{
1323 if (!priv->fatal_error)
1324 return;
1325
1326 priv->fatal_errors[priv->fatal_index++] = priv->fatal_error;
1327 priv->fatal_index %= IPW2100_ERROR_QUEUE;
1328 priv->fatal_error = 0;
1329}
1330
1331
1332/* NOTE: Our interrupt is disabled when this method is called */
1333static int ipw2100_power_cycle_adapter(struct ipw2100_priv *priv)
1334{
1335 u32 reg;
1336 int i;
1337
1338 IPW_DEBUG_INFO("Power cycling the hardware.\n");
1339
1340 ipw2100_hw_set_gpio(priv);
1341
1342 /* Step 1. Stop Master Assert */
1343 write_register(priv->net_dev, IPW_REG_RESET_REG,
1344 IPW_AUX_HOST_RESET_REG_STOP_MASTER);
1345
1346 /* Step 2. Wait for stop Master Assert
1347 * (not more then 50us, otherwise ret error */
1348 i = 5;
1349 do {
1350 udelay(IPW_WAIT_RESET_MASTER_ASSERT_COMPLETE_DELAY);
1351 read_register(priv->net_dev, IPW_REG_RESET_REG, &reg);
1352
1353 if (reg & IPW_AUX_HOST_RESET_REG_MASTER_DISABLED)
1354 break;
1355 } while(i--);
1356
1357 priv->status &= ~STATUS_RESET_PENDING;
1358
1359 if (!i) {
1360 IPW_DEBUG_INFO("exit - waited too long for master assert stop\n");
1361 return -EIO;
1362 }
1363
1364 write_register(priv->net_dev, IPW_REG_RESET_REG,
1365 IPW_AUX_HOST_RESET_REG_SW_RESET);
1366
1367
1368 /* Reset any fatal_error conditions */
1369 ipw2100_reset_fatalerror(priv);
1370
1371 /* At this point, the adapter is now stopped and disabled */
1372 priv->status &= ~(STATUS_RUNNING | STATUS_ASSOCIATING |
1373 STATUS_ASSOCIATED | STATUS_ENABLED);
1374
1375 return 0;
1376}
1377
1378/*
1379 * Send the CARD_DISABLE_PHY_OFF comamnd to the card to disable it
1380 *
1381 * After disabling, if the card was associated, a STATUS_ASSN_LOST will be sent.
1382 *
1383 * STATUS_CARD_DISABLE_NOTIFICATION will be sent regardless of
1384 * if STATUS_ASSN_LOST is sent.
1385 */
1386static int ipw2100_hw_phy_off(struct ipw2100_priv *priv)
1387{
1388
1389#define HW_PHY_OFF_LOOP_DELAY (HZ / 5000)
1390
1391 struct host_command cmd = {
1392 .host_command = CARD_DISABLE_PHY_OFF,
1393 .host_command_sequence = 0,
1394 .host_command_length = 0,
1395 };
1396 int err, i;
1397 u32 val1, val2;
1398
1399 IPW_DEBUG_HC("CARD_DISABLE_PHY_OFF\n");
1400
1401 /* Turn off the radio */
1402 err = ipw2100_hw_send_command(priv, &cmd);
1403 if (err)
1404 return err;
1405
1406 for (i = 0; i < 2500; i++) {
1407 read_nic_dword(priv->net_dev, IPW2100_CONTROL_REG, &val1);
1408 read_nic_dword(priv->net_dev, IPW2100_COMMAND, &val2);
1409
1410 if ((val1 & IPW2100_CONTROL_PHY_OFF) &&
1411 (val2 & IPW2100_COMMAND_PHY_OFF))
1412 return 0;
1413
1414 set_current_state(TASK_UNINTERRUPTIBLE);
1415 schedule_timeout(HW_PHY_OFF_LOOP_DELAY);
1416 }
1417
1418 return -EIO;
1419}
1420
1421
1422static int ipw2100_enable_adapter(struct ipw2100_priv *priv)
1423{
1424 struct host_command cmd = {
1425 .host_command = HOST_COMPLETE,
1426 .host_command_sequence = 0,
1427 .host_command_length = 0
1428 };
1429 int err = 0;
1430
1431 IPW_DEBUG_HC("HOST_COMPLETE\n");
1432
1433 if (priv->status & STATUS_ENABLED)
1434 return 0;
1435
1436 down(&priv->adapter_sem);
1437
1438 if (rf_kill_active(priv)) {
1439 IPW_DEBUG_HC("Command aborted due to RF kill active.\n");
1440 goto fail_up;
1441 }
1442
1443 err = ipw2100_hw_send_command(priv, &cmd);
1444 if (err) {
1445 IPW_DEBUG_INFO("Failed to send HOST_COMPLETE command\n");
1446 goto fail_up;
1447 }
1448
1449 err = ipw2100_wait_for_card_state(priv, IPW_HW_STATE_ENABLED);
1450 if (err) {
1451 IPW_DEBUG_INFO(
1452 "%s: card not responding to init command.\n",
1453 priv->net_dev->name);
1454 goto fail_up;
1455 }
1456
1457 if (priv->stop_hang_check) {
1458 priv->stop_hang_check = 0;
1459 queue_delayed_work(priv->workqueue, &priv->hang_check, HZ / 2);
1460 }
1461
1462fail_up:
1463 up(&priv->adapter_sem);
1464 return err;
1465}
1466
1467static int ipw2100_hw_stop_adapter(struct ipw2100_priv *priv)
1468{
1469#define HW_POWER_DOWN_DELAY (HZ / 10)
1470
1471 struct host_command cmd = {
1472 .host_command = HOST_PRE_POWER_DOWN,
1473 .host_command_sequence = 0,
1474 .host_command_length = 0,
1475 };
1476 int err, i;
1477 u32 reg;
1478
1479 if (!(priv->status & STATUS_RUNNING))
1480 return 0;
1481
1482 priv->status |= STATUS_STOPPING;
1483
1484 /* We can only shut down the card if the firmware is operational. So,
1485 * if we haven't reset since a fatal_error, then we can not send the
1486 * shutdown commands. */
1487 if (!priv->fatal_error) {
1488 /* First, make sure the adapter is enabled so that the PHY_OFF
1489 * command can shut it down */
1490 ipw2100_enable_adapter(priv);
1491
1492 err = ipw2100_hw_phy_off(priv);
1493 if (err)
1494 printk(KERN_WARNING DRV_NAME ": Error disabling radio %d\n", err);
1495
1496 /*
1497 * If in D0-standby mode going directly to D3 may cause a
1498 * PCI bus violation. Therefore we must change out of the D0
1499 * state.
1500 *
1501 * Sending the PREPARE_FOR_POWER_DOWN will restrict the
1502 * hardware from going into standby mode and will transition
1503 * out of D0-standy if it is already in that state.
1504 *
1505 * STATUS_PREPARE_POWER_DOWN_COMPLETE will be sent by the
1506 * driver upon completion. Once received, the driver can
1507 * proceed to the D3 state.
1508 *
1509 * Prepare for power down command to fw. This command would
1510 * take HW out of D0-standby and prepare it for D3 state.
1511 *
1512 * Currently FW does not support event notification for this
1513 * event. Therefore, skip waiting for it. Just wait a fixed
1514 * 100ms
1515 */
1516 IPW_DEBUG_HC("HOST_PRE_POWER_DOWN\n");
1517
1518 err = ipw2100_hw_send_command(priv, &cmd);
1519 if (err)
1520 printk(KERN_WARNING DRV_NAME ": "
1521 "%s: Power down command failed: Error %d\n",
1522 priv->net_dev->name, err);
1523 else {
1524 set_current_state(TASK_UNINTERRUPTIBLE);
1525 schedule_timeout(HW_POWER_DOWN_DELAY);
1526 }
1527 }
1528
1529 priv->status &= ~STATUS_ENABLED;
1530
1531 /*
1532 * Set GPIO 3 writable by FW; GPIO 1 writable
1533 * by driver and enable clock
1534 */
1535 ipw2100_hw_set_gpio(priv);
1536
1537 /*
1538 * Power down adapter. Sequence:
1539 * 1. Stop master assert (RESET_REG[9]=1)
1540 * 2. Wait for stop master (RESET_REG[8]==1)
1541 * 3. S/w reset assert (RESET_REG[7] = 1)
1542 */
1543
1544 /* Stop master assert */
1545 write_register(priv->net_dev, IPW_REG_RESET_REG,
1546 IPW_AUX_HOST_RESET_REG_STOP_MASTER);
1547
1548 /* wait stop master not more than 50 usec.
1549 * Otherwise return error. */
1550 for (i = 5; i > 0; i--) {
1551 udelay(10);
1552
1553 /* Check master stop bit */
1554 read_register(priv->net_dev, IPW_REG_RESET_REG, &reg);
1555
1556 if (reg & IPW_AUX_HOST_RESET_REG_MASTER_DISABLED)
1557 break;
1558 }
1559
1560 if (i == 0)
1561 printk(KERN_WARNING DRV_NAME
1562 ": %s: Could now power down adapter.\n",
1563 priv->net_dev->name);
1564
1565 /* assert s/w reset */
1566 write_register(priv->net_dev, IPW_REG_RESET_REG,
1567 IPW_AUX_HOST_RESET_REG_SW_RESET);
1568
1569 priv->status &= ~(STATUS_RUNNING | STATUS_STOPPING);
1570
1571 return 0;
1572}
1573
1574
1575static int ipw2100_disable_adapter(struct ipw2100_priv *priv)
1576{
1577 struct host_command cmd = {
1578 .host_command = CARD_DISABLE,
1579 .host_command_sequence = 0,
1580 .host_command_length = 0
1581 };
1582 int err = 0;
1583
1584 IPW_DEBUG_HC("CARD_DISABLE\n");
1585
1586 if (!(priv->status & STATUS_ENABLED))
1587 return 0;
1588
1589 /* Make sure we clear the associated state */
1590 priv->status &= ~(STATUS_ASSOCIATED | STATUS_ASSOCIATING);
1591
1592 if (!priv->stop_hang_check) {
1593 priv->stop_hang_check = 1;
1594 cancel_delayed_work(&priv->hang_check);
1595 }
1596
1597 down(&priv->adapter_sem);
1598
1599 err = ipw2100_hw_send_command(priv, &cmd);
1600 if (err) {
1601 printk(KERN_WARNING DRV_NAME ": exit - failed to send CARD_DISABLE command\n");
1602 goto fail_up;
1603 }
1604
1605 err = ipw2100_wait_for_card_state(priv, IPW_HW_STATE_DISABLED);
1606 if (err) {
1607 printk(KERN_WARNING DRV_NAME ": exit - card failed to change to DISABLED\n");
1608 goto fail_up;
1609 }
1610
1611 IPW_DEBUG_INFO("TODO: implement scan state machine\n");
1612
1613fail_up:
1614 up(&priv->adapter_sem);
1615 return err;
1616}
1617
1618static int ipw2100_set_scan_options(struct ipw2100_priv *priv)
1619{
1620 struct host_command cmd = {
1621 .host_command = SET_SCAN_OPTIONS,
1622 .host_command_sequence = 0,
1623 .host_command_length = 8
1624 };
1625 int err;
1626
1627 IPW_DEBUG_INFO("enter\n");
1628
1629 IPW_DEBUG_SCAN("setting scan options\n");
1630
1631 cmd.host_command_parameters[0] = 0;
1632
1633 if (!(priv->config & CFG_ASSOCIATE))
1634 cmd.host_command_parameters[0] |= IPW_SCAN_NOASSOCIATE;
1635 if ((priv->sec.flags & SEC_ENABLED) && priv->sec.enabled)
1636 cmd.host_command_parameters[0] |= IPW_SCAN_MIXED_CELL;
1637 if (priv->config & CFG_PASSIVE_SCAN)
1638 cmd.host_command_parameters[0] |= IPW_SCAN_PASSIVE;
1639
1640 cmd.host_command_parameters[1] = priv->channel_mask;
1641
1642 err = ipw2100_hw_send_command(priv, &cmd);
1643
1644 IPW_DEBUG_HC("SET_SCAN_OPTIONS 0x%04X\n",
1645 cmd.host_command_parameters[0]);
1646
1647 return err;
1648}
1649
1650static int ipw2100_start_scan(struct ipw2100_priv *priv)
1651{
1652 struct host_command cmd = {
1653 .host_command = BROADCAST_SCAN,
1654 .host_command_sequence = 0,
1655 .host_command_length = 4
1656 };
1657 int err;
1658
1659 IPW_DEBUG_HC("START_SCAN\n");
1660
1661 cmd.host_command_parameters[0] = 0;
1662
1663 /* No scanning if in monitor mode */
1664 if (priv->ieee->iw_mode == IW_MODE_MONITOR)
1665 return 1;
1666
1667 if (priv->status & STATUS_SCANNING) {
1668 IPW_DEBUG_SCAN("Scan requested while already in scan...\n");
1669 return 0;
1670 }
1671
1672 IPW_DEBUG_INFO("enter\n");
1673
1674 /* Not clearing here; doing so makes iwlist always return nothing...
1675 *
1676 * We should modify the table logic to use aging tables vs. clearing
1677 * the table on each scan start.
1678 */
1679 IPW_DEBUG_SCAN("starting scan\n");
1680
1681 priv->status |= STATUS_SCANNING;
1682 err = ipw2100_hw_send_command(priv, &cmd);
1683 if (err)
1684 priv->status &= ~STATUS_SCANNING;
1685
1686 IPW_DEBUG_INFO("exit\n");
1687
1688 return err;
1689}
1690
1691static int ipw2100_up(struct ipw2100_priv *priv, int deferred)
1692{
1693 unsigned long flags;
1694 int rc = 0;
1695 u32 lock;
1696 u32 ord_len = sizeof(lock);
1697
1698 /* Quite if manually disabled. */
1699 if (priv->status & STATUS_RF_KILL_SW) {
1700 IPW_DEBUG_INFO("%s: Radio is disabled by Manual Disable "
1701 "switch\n", priv->net_dev->name);
1702 return 0;
1703 }
1704
1705 /* If the interrupt is enabled, turn it off... */
1706 spin_lock_irqsave(&priv->low_lock, flags);
1707 ipw2100_disable_interrupts(priv);
1708
1709 /* Reset any fatal_error conditions */
1710 ipw2100_reset_fatalerror(priv);
1711 spin_unlock_irqrestore(&priv->low_lock, flags);
1712
1713 if (priv->status & STATUS_POWERED ||
1714 (priv->status & STATUS_RESET_PENDING)) {
1715 /* Power cycle the card ... */
1716 if (ipw2100_power_cycle_adapter(priv)) {
1717 printk(KERN_WARNING DRV_NAME ": %s: Could not cycle adapter.\n",
1718 priv->net_dev->name);
1719 rc = 1;
1720 goto exit;
1721 }
1722 } else
1723 priv->status |= STATUS_POWERED;
1724
1725 /* Load the firmware, start the clocks, etc. */
1726 if (ipw2100_start_adapter(priv)) {
1727 printk(KERN_ERR DRV_NAME ": %s: Failed to start the firmware.\n",
1728 priv->net_dev->name);
1729 rc = 1;
1730 goto exit;
1731 }
1732
1733 ipw2100_initialize_ordinals(priv);
1734
1735 /* Determine capabilities of this particular HW configuration */
1736 if (ipw2100_get_hw_features(priv)) {
1737 printk(KERN_ERR DRV_NAME ": %s: Failed to determine HW features.\n",
1738 priv->net_dev->name);
1739 rc = 1;
1740 goto exit;
1741 }
1742
1743 lock = LOCK_NONE;
1744 if (ipw2100_set_ordinal(priv, IPW_ORD_PERS_DB_LOCK, &lock, &ord_len)) {
1745 printk(KERN_ERR DRV_NAME ": %s: Failed to clear ordinal lock.\n",
1746 priv->net_dev->name);
1747 rc = 1;
1748 goto exit;
1749 }
1750
1751 priv->status &= ~STATUS_SCANNING;
1752
1753 if (rf_kill_active(priv)) {
1754 printk(KERN_INFO "%s: Radio is disabled by RF switch.\n",
1755 priv->net_dev->name);
1756
1757 if (priv->stop_rf_kill) {
1758 priv->stop_rf_kill = 0;
1759 queue_delayed_work(priv->workqueue, &priv->rf_kill, HZ);
1760 }
1761
1762 deferred = 1;
1763 }
1764
1765 /* Turn on the interrupt so that commands can be processed */
1766 ipw2100_enable_interrupts(priv);
1767
1768 /* Send all of the commands that must be sent prior to
1769 * HOST_COMPLETE */
1770 if (ipw2100_adapter_setup(priv)) {
1771 printk(KERN_ERR DRV_NAME ": %s: Failed to start the card.\n",
1772 priv->net_dev->name);
1773 rc = 1;
1774 goto exit;
1775 }
1776
1777 if (!deferred) {
1778 /* Enable the adapter - sends HOST_COMPLETE */
1779 if (ipw2100_enable_adapter(priv)) {
1780 printk(KERN_ERR DRV_NAME ": "
1781 "%s: failed in call to enable adapter.\n",
1782 priv->net_dev->name);
1783 ipw2100_hw_stop_adapter(priv);
1784 rc = 1;
1785 goto exit;
1786 }
1787
1788
1789 /* Start a scan . . . */
1790 ipw2100_set_scan_options(priv);
1791 ipw2100_start_scan(priv);
1792 }
1793
1794 exit:
1795 return rc;
1796}
1797
1798/* Called by register_netdev() */
1799static int ipw2100_net_init(struct net_device *dev)
1800{
1801 struct ipw2100_priv *priv = ieee80211_priv(dev);
1802 return ipw2100_up(priv, 1);
1803}
1804
1805static void ipw2100_down(struct ipw2100_priv *priv)
1806{
1807 unsigned long flags;
1808 union iwreq_data wrqu = {
1809 .ap_addr = {
1810 .sa_family = ARPHRD_ETHER
1811 }
1812 };
1813 int associated = priv->status & STATUS_ASSOCIATED;
1814
1815 /* Kill the RF switch timer */
1816 if (!priv->stop_rf_kill) {
1817 priv->stop_rf_kill = 1;
1818 cancel_delayed_work(&priv->rf_kill);
1819 }
1820
1821 /* Kill the firmare hang check timer */
1822 if (!priv->stop_hang_check) {
1823 priv->stop_hang_check = 1;
1824 cancel_delayed_work(&priv->hang_check);
1825 }
1826
1827 /* Kill any pending resets */
1828 if (priv->status & STATUS_RESET_PENDING)
1829 cancel_delayed_work(&priv->reset_work);
1830
1831 /* Make sure the interrupt is on so that FW commands will be
1832 * processed correctly */
1833 spin_lock_irqsave(&priv->low_lock, flags);
1834 ipw2100_enable_interrupts(priv);
1835 spin_unlock_irqrestore(&priv->low_lock, flags);
1836
1837 if (ipw2100_hw_stop_adapter(priv))
1838 printk(KERN_ERR DRV_NAME ": %s: Error stopping adapter.\n",
1839 priv->net_dev->name);
1840
1841 /* Do not disable the interrupt until _after_ we disable
1842 * the adaptor. Otherwise the CARD_DISABLE command will never
1843 * be ack'd by the firmware */
1844 spin_lock_irqsave(&priv->low_lock, flags);
1845 ipw2100_disable_interrupts(priv);
1846 spin_unlock_irqrestore(&priv->low_lock, flags);
1847
1848#ifdef ACPI_CSTATE_LIMIT_DEFINED
1849 if (priv->config & CFG_C3_DISABLED) {
1850 IPW_DEBUG_INFO(DRV_NAME ": Resetting C3 transitions.\n");
1851 acpi_set_cstate_limit(priv->cstate_limit);
1852 priv->config &= ~CFG_C3_DISABLED;
1853 }
1854#endif
1855
1856 /* We have to signal any supplicant if we are disassociating */
1857 if (associated)
1858 wireless_send_event(priv->net_dev, SIOCGIWAP, &wrqu, NULL);
1859
1860 priv->status &= ~(STATUS_ASSOCIATED | STATUS_ASSOCIATING);
1861 netif_carrier_off(priv->net_dev);
1862 netif_stop_queue(priv->net_dev);
1863}
1864
1865static void ipw2100_reset_adapter(struct ipw2100_priv *priv)
1866{
1867 unsigned long flags;
1868 union iwreq_data wrqu = {
1869 .ap_addr = {
1870 .sa_family = ARPHRD_ETHER
1871 }
1872 };
1873 int associated = priv->status & STATUS_ASSOCIATED;
1874
1875 spin_lock_irqsave(&priv->low_lock, flags);
1876 IPW_DEBUG_INFO(DRV_NAME ": %s: Restarting adapter.\n",
1877 priv->net_dev->name);
1878 priv->resets++;
1879 priv->status &= ~(STATUS_ASSOCIATED | STATUS_ASSOCIATING);
1880 priv->status |= STATUS_SECURITY_UPDATED;
1881
1882 /* Force a power cycle even if interface hasn't been opened
1883 * yet */
1884 cancel_delayed_work(&priv->reset_work);
1885 priv->status |= STATUS_RESET_PENDING;
1886 spin_unlock_irqrestore(&priv->low_lock, flags);
1887
1888 down(&priv->action_sem);
1889 /* stop timed checks so that they don't interfere with reset */
1890 priv->stop_hang_check = 1;
1891 cancel_delayed_work(&priv->hang_check);
1892
1893 /* We have to signal any supplicant if we are disassociating */
1894 if (associated)
1895 wireless_send_event(priv->net_dev, SIOCGIWAP, &wrqu, NULL);
1896
1897 ipw2100_up(priv, 0);
1898 up(&priv->action_sem);
1899
1900}
1901
1902
1903static void isr_indicate_associated(struct ipw2100_priv *priv, u32 status)
1904{
1905
1906#define MAC_ASSOCIATION_READ_DELAY (HZ)
1907 int ret, len, essid_len;
1908 char essid[IW_ESSID_MAX_SIZE];
1909 u32 txrate;
1910 u32 chan;
1911 char *txratename;
1912 u8 bssid[ETH_ALEN];
1913
1914 /*
1915 * TBD: BSSID is usually 00:00:00:00:00:00 here and not
1916 * an actual MAC of the AP. Seems like FW sets this
1917 * address too late. Read it later and expose through
1918 * /proc or schedule a later task to query and update
1919 */
1920
1921 essid_len = IW_ESSID_MAX_SIZE;
1922 ret = ipw2100_get_ordinal(priv, IPW_ORD_STAT_ASSN_SSID,
1923 essid, &essid_len);
1924 if (ret) {
1925 IPW_DEBUG_INFO("failed querying ordinals at line %d\n",
1926 __LINE__);
1927 return;
1928 }
1929
1930 len = sizeof(u32);
1931 ret = ipw2100_get_ordinal(priv, IPW_ORD_CURRENT_TX_RATE,
1932 &txrate, &len);
1933 if (ret) {
1934 IPW_DEBUG_INFO("failed querying ordinals at line %d\n",
1935 __LINE__);
1936 return;
1937 }
1938
1939 len = sizeof(u32);
1940 ret = ipw2100_get_ordinal(priv, IPW_ORD_OUR_FREQ, &chan, &len);
1941 if (ret) {
1942 IPW_DEBUG_INFO("failed querying ordinals at line %d\n",
1943 __LINE__);
1944 return;
1945 }
1946 len = ETH_ALEN;
1947 ipw2100_get_ordinal(priv, IPW_ORD_STAT_ASSN_AP_BSSID, &bssid, &len);
1948 if (ret) {
1949 IPW_DEBUG_INFO("failed querying ordinals at line %d\n",
1950 __LINE__);
1951 return;
1952 }
1953 memcpy(priv->ieee->bssid, bssid, ETH_ALEN);
1954
1955
1956 switch (txrate) {
1957 case TX_RATE_1_MBIT:
1958 txratename = "1Mbps";
1959 break;
1960 case TX_RATE_2_MBIT:
1961 txratename = "2Mbsp";
1962 break;
1963 case TX_RATE_5_5_MBIT:
1964 txratename = "5.5Mbps";
1965 break;
1966 case TX_RATE_11_MBIT:
1967 txratename = "11Mbps";
1968 break;
1969 default:
1970 IPW_DEBUG_INFO("Unknown rate: %d\n", txrate);
1971 txratename = "unknown rate";
1972 break;
1973 }
1974
1975 IPW_DEBUG_INFO("%s: Associated with '%s' at %s, channel %d (BSSID="
1976 MAC_FMT ")\n",
1977 priv->net_dev->name, escape_essid(essid, essid_len),
1978 txratename, chan, MAC_ARG(bssid));
1979
1980 /* now we copy read ssid into dev */
1981 if (!(priv->config & CFG_STATIC_ESSID)) {
1982 priv->essid_len = min((u8)essid_len, (u8)IW_ESSID_MAX_SIZE);
1983 memcpy(priv->essid, essid, priv->essid_len);
1984 }
1985 priv->channel = chan;
1986 memcpy(priv->bssid, bssid, ETH_ALEN);
1987
1988 priv->status |= STATUS_ASSOCIATING;
1989 priv->connect_start = get_seconds();
1990
1991 queue_delayed_work(priv->workqueue, &priv->wx_event_work, HZ / 10);
1992}
1993
1994
1995static int ipw2100_set_essid(struct ipw2100_priv *priv, char *essid,
1996 int length, int batch_mode)
1997{
1998 int ssid_len = min(length, IW_ESSID_MAX_SIZE);
1999 struct host_command cmd = {
2000 .host_command = SSID,
2001 .host_command_sequence = 0,
2002 .host_command_length = ssid_len
2003 };
2004 int err;
2005
2006 IPW_DEBUG_HC("SSID: '%s'\n", escape_essid(essid, ssid_len));
2007
2008 if (ssid_len)
2009 memcpy((char*)cmd.host_command_parameters,
2010 essid, ssid_len);
2011
2012 if (!batch_mode) {
2013 err = ipw2100_disable_adapter(priv);
2014 if (err)
2015 return err;
2016 }
2017
2018 /* Bug in FW currently doesn't honor bit 0 in SET_SCAN_OPTIONS to
2019 * disable auto association -- so we cheat by setting a bogus SSID */
2020 if (!ssid_len && !(priv->config & CFG_ASSOCIATE)) {
2021 int i;
2022 u8 *bogus = (u8*)cmd.host_command_parameters;
2023 for (i = 0; i < IW_ESSID_MAX_SIZE; i++)
2024 bogus[i] = 0x18 + i;
2025 cmd.host_command_length = IW_ESSID_MAX_SIZE;
2026 }
2027
2028 /* NOTE: We always send the SSID command even if the provided ESSID is
2029 * the same as what we currently think is set. */
2030
2031 err = ipw2100_hw_send_command(priv, &cmd);
2032 if (!err) {
2033 memset(priv->essid + ssid_len, 0,
2034 IW_ESSID_MAX_SIZE - ssid_len);
2035 memcpy(priv->essid, essid, ssid_len);
2036 priv->essid_len = ssid_len;
2037 }
2038
2039 if (!batch_mode) {
2040 if (ipw2100_enable_adapter(priv))
2041 err = -EIO;
2042 }
2043
2044 return err;
2045}
2046
2047static void isr_indicate_association_lost(struct ipw2100_priv *priv, u32 status)
2048{
2049 IPW_DEBUG(IPW_DL_NOTIF | IPW_DL_STATE | IPW_DL_ASSOC,
2050 "disassociated: '%s' " MAC_FMT " \n",
2051 escape_essid(priv->essid, priv->essid_len),
2052 MAC_ARG(priv->bssid));
2053
2054 priv->status &= ~(STATUS_ASSOCIATED | STATUS_ASSOCIATING);
2055
2056 if (priv->status & STATUS_STOPPING) {
2057 IPW_DEBUG_INFO("Card is stopping itself, discard ASSN_LOST.\n");
2058 return;
2059 }
2060
2061 memset(priv->bssid, 0, ETH_ALEN);
2062 memset(priv->ieee->bssid, 0, ETH_ALEN);
2063
2064 netif_carrier_off(priv->net_dev);
2065 netif_stop_queue(priv->net_dev);
2066
2067 if (!(priv->status & STATUS_RUNNING))
2068 return;
2069
2070 if (priv->status & STATUS_SECURITY_UPDATED)
2071 queue_work(priv->workqueue, &priv->security_work);
2072
2073 queue_work(priv->workqueue, &priv->wx_event_work);
2074}
2075
2076static void isr_indicate_rf_kill(struct ipw2100_priv *priv, u32 status)
2077{
2078 IPW_DEBUG_INFO("%s: RF Kill state changed to radio OFF.\n",
2079 priv->net_dev->name);
2080
2081 /* RF_KILL is now enabled (else we wouldn't be here) */
2082 priv->status |= STATUS_RF_KILL_HW;
2083
2084#ifdef ACPI_CSTATE_LIMIT_DEFINED
2085 if (priv->config & CFG_C3_DISABLED) {
2086 IPW_DEBUG_INFO(DRV_NAME ": Resetting C3 transitions.\n");
2087 acpi_set_cstate_limit(priv->cstate_limit);
2088 priv->config &= ~CFG_C3_DISABLED;
2089 }
2090#endif
2091
2092 /* Make sure the RF Kill check timer is running */
2093 priv->stop_rf_kill = 0;
2094 cancel_delayed_work(&priv->rf_kill);
2095 queue_delayed_work(priv->workqueue, &priv->rf_kill, HZ);
2096}
2097
2098static void isr_scan_complete(struct ipw2100_priv *priv, u32 status)
2099{
2100 IPW_DEBUG_SCAN("scan complete\n");
2101 /* Age the scan results... */
2102 priv->ieee->scans++;
2103 priv->status &= ~STATUS_SCANNING;
2104}
2105
2106#ifdef CONFIG_IPW_DEBUG
2107#define IPW2100_HANDLER(v, f) { v, f, # v }
2108struct ipw2100_status_indicator {
2109 int status;
2110 void (*cb)(struct ipw2100_priv *priv, u32 status);
2111 char *name;
2112};
2113#else
2114#define IPW2100_HANDLER(v, f) { v, f }
2115struct ipw2100_status_indicator {
2116 int status;
2117 void (*cb)(struct ipw2100_priv *priv, u32 status);
2118};
2119#endif /* CONFIG_IPW_DEBUG */
2120
2121static void isr_indicate_scanning(struct ipw2100_priv *priv, u32 status)
2122{
2123 IPW_DEBUG_SCAN("Scanning...\n");
2124 priv->status |= STATUS_SCANNING;
2125}
2126
2127static const struct ipw2100_status_indicator status_handlers[] = {
2128 IPW2100_HANDLER(IPW_STATE_INITIALIZED, 0),
2129 IPW2100_HANDLER(IPW_STATE_COUNTRY_FOUND, 0),
2130 IPW2100_HANDLER(IPW_STATE_ASSOCIATED, isr_indicate_associated),
2131 IPW2100_HANDLER(IPW_STATE_ASSN_LOST, isr_indicate_association_lost),
2132 IPW2100_HANDLER(IPW_STATE_ASSN_CHANGED, 0),
2133 IPW2100_HANDLER(IPW_STATE_SCAN_COMPLETE, isr_scan_complete),
2134 IPW2100_HANDLER(IPW_STATE_ENTERED_PSP, 0),
2135 IPW2100_HANDLER(IPW_STATE_LEFT_PSP, 0),
2136 IPW2100_HANDLER(IPW_STATE_RF_KILL, isr_indicate_rf_kill),
2137 IPW2100_HANDLER(IPW_STATE_DISABLED, 0),
2138 IPW2100_HANDLER(IPW_STATE_POWER_DOWN, 0),
2139 IPW2100_HANDLER(IPW_STATE_SCANNING, isr_indicate_scanning),
2140 IPW2100_HANDLER(-1, 0)
2141};
2142
2143
2144static void isr_status_change(struct ipw2100_priv *priv, int status)
2145{
2146 int i;
2147
2148 if (status == IPW_STATE_SCANNING &&
2149 priv->status & STATUS_ASSOCIATED &&
2150 !(priv->status & STATUS_SCANNING)) {
2151 IPW_DEBUG_INFO("Scan detected while associated, with "
2152 "no scan request. Restarting firmware.\n");
2153
2154 /* Wake up any sleeping jobs */
2155 schedule_reset(priv);
2156 }
2157
2158 for (i = 0; status_handlers[i].status != -1; i++) {
2159 if (status == status_handlers[i].status) {
2160 IPW_DEBUG_NOTIF("Status change: %s\n",
2161 status_handlers[i].name);
2162 if (status_handlers[i].cb)
2163 status_handlers[i].cb(priv, status);
2164 priv->wstats.status = status;
2165 return;
2166 }
2167 }
2168
2169 IPW_DEBUG_NOTIF("unknown status received: %04x\n", status);
2170}
2171
2172static void isr_rx_complete_command(
2173 struct ipw2100_priv *priv,
2174 struct ipw2100_cmd_header *cmd)
2175{
2176#ifdef CONFIG_IPW_DEBUG
2177 if (cmd->host_command_reg < ARRAY_SIZE(command_types)) {
2178 IPW_DEBUG_HC("Command completed '%s (%d)'\n",
2179 command_types[cmd->host_command_reg],
2180 cmd->host_command_reg);
2181 }
2182#endif
2183 if (cmd->host_command_reg == HOST_COMPLETE)
2184 priv->status |= STATUS_ENABLED;
2185
2186 if (cmd->host_command_reg == CARD_DISABLE)
2187 priv->status &= ~STATUS_ENABLED;
2188
2189 priv->status &= ~STATUS_CMD_ACTIVE;
2190
2191 wake_up_interruptible(&priv->wait_command_queue);
2192}
2193
2194#ifdef CONFIG_IPW_DEBUG
2195static const char *frame_types[] = {
2196 "COMMAND_STATUS_VAL",
2197 "STATUS_CHANGE_VAL",
2198 "P80211_DATA_VAL",
2199 "P8023_DATA_VAL",
2200 "HOST_NOTIFICATION_VAL"
2201};
2202#endif
2203
2204
2205static inline int ipw2100_alloc_skb(
2206 struct ipw2100_priv *priv,
2207 struct ipw2100_rx_packet *packet)
2208{
2209 packet->skb = dev_alloc_skb(sizeof(struct ipw2100_rx));
2210 if (!packet->skb)
2211 return -ENOMEM;
2212
2213 packet->rxp = (struct ipw2100_rx *)packet->skb->data;
2214 packet->dma_addr = pci_map_single(priv->pci_dev, packet->skb->data,
2215 sizeof(struct ipw2100_rx),
2216 PCI_DMA_FROMDEVICE);
2217 /* NOTE: pci_map_single does not return an error code, and 0 is a valid
2218 * dma_addr */
2219
2220 return 0;
2221}
2222
2223
2224#define SEARCH_ERROR 0xffffffff
2225#define SEARCH_FAIL 0xfffffffe
2226#define SEARCH_SUCCESS 0xfffffff0
2227#define SEARCH_DISCARD 0
2228#define SEARCH_SNAPSHOT 1
2229
2230#define SNAPSHOT_ADDR(ofs) (priv->snapshot[((ofs) >> 12) & 0xff] + ((ofs) & 0xfff))
2231static inline int ipw2100_snapshot_alloc(struct ipw2100_priv *priv)
2232{
2233 int i;
2234 if (priv->snapshot[0])
2235 return 1;
2236 for (i = 0; i < 0x30; i++) {
2237 priv->snapshot[i] = (u8*)kmalloc(0x1000, GFP_ATOMIC);
2238 if (!priv->snapshot[i]) {
2239 IPW_DEBUG_INFO("%s: Error allocating snapshot "
2240 "buffer %d\n", priv->net_dev->name, i);
2241 while (i > 0)
2242 kfree(priv->snapshot[--i]);
2243 priv->snapshot[0] = NULL;
2244 return 0;
2245 }
2246 }
2247
2248 return 1;
2249}
2250
2251static inline void ipw2100_snapshot_free(struct ipw2100_priv *priv)
2252{
2253 int i;
2254 if (!priv->snapshot[0])
2255 return;
2256 for (i = 0; i < 0x30; i++)
2257 kfree(priv->snapshot[i]);
2258 priv->snapshot[0] = NULL;
2259}
2260
2261static inline u32 ipw2100_match_buf(struct ipw2100_priv *priv, u8 *in_buf,
2262 size_t len, int mode)
2263{
2264 u32 i, j;
2265 u32 tmp;
2266 u8 *s, *d;
2267 u32 ret;
2268
2269 s = in_buf;
2270 if (mode == SEARCH_SNAPSHOT) {
2271 if (!ipw2100_snapshot_alloc(priv))
2272 mode = SEARCH_DISCARD;
2273 }
2274
2275 for (ret = SEARCH_FAIL, i = 0; i < 0x30000; i += 4) {
2276 read_nic_dword(priv->net_dev, i, &tmp);
2277 if (mode == SEARCH_SNAPSHOT)
2278 *(u32 *)SNAPSHOT_ADDR(i) = tmp;
2279 if (ret == SEARCH_FAIL) {
2280 d = (u8*)&tmp;
2281 for (j = 0; j < 4; j++) {
2282 if (*s != *d) {
2283 s = in_buf;
2284 continue;
2285 }
2286
2287 s++;
2288 d++;
2289
2290 if ((s - in_buf) == len)
2291 ret = (i + j) - len + 1;
2292 }
2293 } else if (mode == SEARCH_DISCARD)
2294 return ret;
2295 }
2296
2297 return ret;
2298}
2299
2300/*
2301 *
2302 * 0) Disconnect the SKB from the firmware (just unmap)
2303 * 1) Pack the ETH header into the SKB
2304 * 2) Pass the SKB to the network stack
2305 *
2306 * When packet is provided by the firmware, it contains the following:
2307 *
2308 * . ieee80211_hdr
2309 * . ieee80211_snap_hdr
2310 *
2311 * The size of the constructed ethernet
2312 *
2313 */
2314#ifdef CONFIG_IPW2100_RX_DEBUG
2315static u8 packet_data[IPW_RX_NIC_BUFFER_LENGTH];
2316#endif
2317
2318static inline void ipw2100_corruption_detected(struct ipw2100_priv *priv,
2319 int i)
2320{
2321#ifdef CONFIG_IPW_DEBUG_C3
2322 struct ipw2100_status *status = &priv->status_queue.drv[i];
2323 u32 match, reg;
2324 int j;
2325#endif
2326#ifdef ACPI_CSTATE_LIMIT_DEFINED
2327 int limit;
2328#endif
2329
2330 IPW_DEBUG_INFO(DRV_NAME ": PCI latency error detected at "
2331 "0x%04zX.\n", i * sizeof(struct ipw2100_status));
2332
2333#ifdef ACPI_CSTATE_LIMIT_DEFINED
2334 IPW_DEBUG_INFO(DRV_NAME ": Disabling C3 transitions.\n");
2335 limit = acpi_get_cstate_limit();
2336 if (limit > 2) {
2337 priv->cstate_limit = limit;
2338 acpi_set_cstate_limit(2);
2339 priv->config |= CFG_C3_DISABLED;
2340 }
2341#endif
2342
2343#ifdef CONFIG_IPW_DEBUG_C3
2344 /* Halt the fimrware so we can get a good image */
2345 write_register(priv->net_dev, IPW_REG_RESET_REG,
2346 IPW_AUX_HOST_RESET_REG_STOP_MASTER);
2347 j = 5;
2348 do {
2349 udelay(IPW_WAIT_RESET_MASTER_ASSERT_COMPLETE_DELAY);
2350 read_register(priv->net_dev, IPW_REG_RESET_REG, &reg);
2351
2352 if (reg & IPW_AUX_HOST_RESET_REG_MASTER_DISABLED)
2353 break;
2354 } while (j--);
2355
2356 match = ipw2100_match_buf(priv, (u8*)status,
2357 sizeof(struct ipw2100_status),
2358 SEARCH_SNAPSHOT);
2359 if (match < SEARCH_SUCCESS)
2360 IPW_DEBUG_INFO("%s: DMA status match in Firmware at "
2361 "offset 0x%06X, length %d:\n",
2362 priv->net_dev->name, match,
2363 sizeof(struct ipw2100_status));
2364 else
2365 IPW_DEBUG_INFO("%s: No DMA status match in "
2366 "Firmware.\n", priv->net_dev->name);
2367
2368 printk_buf((u8*)priv->status_queue.drv,
2369 sizeof(struct ipw2100_status) * RX_QUEUE_LENGTH);
2370#endif
2371
2372 priv->fatal_error = IPW2100_ERR_C3_CORRUPTION;
2373 priv->ieee->stats.rx_errors++;
2374 schedule_reset(priv);
2375}
2376
2377static inline void isr_rx(struct ipw2100_priv *priv, int i,
2378 struct ieee80211_rx_stats *stats)
2379{
2380 struct ipw2100_status *status = &priv->status_queue.drv[i];
2381 struct ipw2100_rx_packet *packet = &priv->rx_buffers[i];
2382
2383 IPW_DEBUG_RX("Handler...\n");
2384
2385 if (unlikely(status->frame_size > skb_tailroom(packet->skb))) {
2386 IPW_DEBUG_INFO("%s: frame_size (%u) > skb_tailroom (%u)!"
2387 " Dropping.\n",
2388 priv->net_dev->name,
2389 status->frame_size, skb_tailroom(packet->skb));
2390 priv->ieee->stats.rx_errors++;
2391 return;
2392 }
2393
2394 if (unlikely(!netif_running(priv->net_dev))) {
2395 priv->ieee->stats.rx_errors++;
2396 priv->wstats.discard.misc++;
2397 IPW_DEBUG_DROP("Dropping packet while interface is not up.\n");
2398 return;
2399 }
2400
2401 if (unlikely(priv->ieee->iw_mode == IW_MODE_MONITOR &&
2402 status->flags & IPW_STATUS_FLAG_CRC_ERROR)) {
2403 IPW_DEBUG_RX("CRC error in packet. Dropping.\n");
2404 priv->ieee->stats.rx_errors++;
2405 return;
2406 }
2407
2408 if (unlikely(priv->ieee->iw_mode != IW_MODE_MONITOR &&
2409 !(priv->status & STATUS_ASSOCIATED))) {
2410 IPW_DEBUG_DROP("Dropping packet while not associated.\n");
2411 priv->wstats.discard.misc++;
2412 return;
2413 }
2414
2415
2416 pci_unmap_single(priv->pci_dev,
2417 packet->dma_addr,
2418 sizeof(struct ipw2100_rx),
2419 PCI_DMA_FROMDEVICE);
2420
2421 skb_put(packet->skb, status->frame_size);
2422
2423#ifdef CONFIG_IPW2100_RX_DEBUG
2424 /* Make a copy of the frame so we can dump it to the logs if
2425 * ieee80211_rx fails */
2426 memcpy(packet_data, packet->skb->data,
2427 min_t(u32, status->frame_size, IPW_RX_NIC_BUFFER_LENGTH));
2428#endif
2429
2430 if (!ieee80211_rx(priv->ieee, packet->skb, stats)) {
2431#ifdef CONFIG_IPW2100_RX_DEBUG
2432 IPW_DEBUG_DROP("%s: Non consumed packet:\n",
2433 priv->net_dev->name);
2434 printk_buf(IPW_DL_DROP, packet_data, status->frame_size);
2435#endif
2436 priv->ieee->stats.rx_errors++;
2437
2438 /* ieee80211_rx failed, so it didn't free the SKB */
2439 dev_kfree_skb_any(packet->skb);
2440 packet->skb = NULL;
2441 }
2442
2443 /* We need to allocate a new SKB and attach it to the RDB. */
2444 if (unlikely(ipw2100_alloc_skb(priv, packet))) {
2445 printk(KERN_WARNING DRV_NAME ": "
2446 "%s: Unable to allocate SKB onto RBD ring - disabling "
2447 "adapter.\n", priv->net_dev->name);
2448 /* TODO: schedule adapter shutdown */
2449 IPW_DEBUG_INFO("TODO: Shutdown adapter...\n");
2450 }
2451
2452 /* Update the RDB entry */
2453 priv->rx_queue.drv[i].host_addr = packet->dma_addr;
2454}
2455
2456static inline int ipw2100_corruption_check(struct ipw2100_priv *priv, int i)
2457{
2458 struct ipw2100_status *status = &priv->status_queue.drv[i];
2459 struct ipw2100_rx *u = priv->rx_buffers[i].rxp;
2460 u16 frame_type = status->status_fields & STATUS_TYPE_MASK;
2461
2462 switch (frame_type) {
2463 case COMMAND_STATUS_VAL:
2464 return (status->frame_size != sizeof(u->rx_data.command));
2465 case STATUS_CHANGE_VAL:
2466 return (status->frame_size != sizeof(u->rx_data.status));
2467 case HOST_NOTIFICATION_VAL:
2468 return (status->frame_size < sizeof(u->rx_data.notification));
2469 case P80211_DATA_VAL:
2470 case P8023_DATA_VAL:
2471#ifdef CONFIG_IPW2100_MONITOR
2472 return 0;
2473#else
2474 switch (WLAN_FC_GET_TYPE(u->rx_data.header.frame_ctl)) {
2475 case IEEE80211_FTYPE_MGMT:
2476 case IEEE80211_FTYPE_CTL:
2477 return 0;
2478 case IEEE80211_FTYPE_DATA:
2479 return (status->frame_size >
2480 IPW_MAX_802_11_PAYLOAD_LENGTH);
2481 }
2482#endif
2483 }
2484
2485 return 1;
2486}
2487
2488/*
2489 * ipw2100 interrupts are disabled at this point, and the ISR
2490 * is the only code that calls this method. So, we do not need
2491 * to play with any locks.
2492 *
2493 * RX Queue works as follows:
2494 *
2495 * Read index - firmware places packet in entry identified by the
2496 * Read index and advances Read index. In this manner,
2497 * Read index will always point to the next packet to
2498 * be filled--but not yet valid.
2499 *
2500 * Write index - driver fills this entry with an unused RBD entry.
2501 * This entry has not filled by the firmware yet.
2502 *
2503 * In between the W and R indexes are the RBDs that have been received
2504 * but not yet processed.
2505 *
2506 * The process of handling packets will start at WRITE + 1 and advance
2507 * until it reaches the READ index.
2508 *
2509 * The WRITE index is cached in the variable 'priv->rx_queue.next'.
2510 *
2511 */
2512static inline void __ipw2100_rx_process(struct ipw2100_priv *priv)
2513{
2514 struct ipw2100_bd_queue *rxq = &priv->rx_queue;
2515 struct ipw2100_status_queue *sq = &priv->status_queue;
2516 struct ipw2100_rx_packet *packet;
2517 u16 frame_type;
2518 u32 r, w, i, s;
2519 struct ipw2100_rx *u;
2520 struct ieee80211_rx_stats stats = {
2521 .mac_time = jiffies,
2522 };
2523
2524 read_register(priv->net_dev, IPW_MEM_HOST_SHARED_RX_READ_INDEX, &r);
2525 read_register(priv->net_dev, IPW_MEM_HOST_SHARED_RX_WRITE_INDEX, &w);
2526
2527 if (r >= rxq->entries) {
2528 IPW_DEBUG_RX("exit - bad read index\n");
2529 return;
2530 }
2531
2532 i = (rxq->next + 1) % rxq->entries;
2533 s = i;
2534 while (i != r) {
2535 /* IPW_DEBUG_RX("r = %d : w = %d : processing = %d\n",
2536 r, rxq->next, i); */
2537
2538 packet = &priv->rx_buffers[i];
2539
2540 /* Sync the DMA for the STATUS buffer so CPU is sure to get
2541 * the correct values */
2542 pci_dma_sync_single_for_cpu(
2543 priv->pci_dev,
2544 sq->nic + sizeof(struct ipw2100_status) * i,
2545 sizeof(struct ipw2100_status),
2546 PCI_DMA_FROMDEVICE);
2547
2548 /* Sync the DMA for the RX buffer so CPU is sure to get
2549 * the correct values */
2550 pci_dma_sync_single_for_cpu(priv->pci_dev, packet->dma_addr,
2551 sizeof(struct ipw2100_rx),
2552 PCI_DMA_FROMDEVICE);
2553
2554 if (unlikely(ipw2100_corruption_check(priv, i))) {
2555 ipw2100_corruption_detected(priv, i);
2556 goto increment;
2557 }
2558
2559 u = packet->rxp;
2560 frame_type = sq->drv[i].status_fields &
2561 STATUS_TYPE_MASK;
2562 stats.rssi = sq->drv[i].rssi + IPW2100_RSSI_TO_DBM;
2563 stats.len = sq->drv[i].frame_size;
2564
2565 stats.mask = 0;
2566 if (stats.rssi != 0)
2567 stats.mask |= IEEE80211_STATMASK_RSSI;
2568 stats.freq = IEEE80211_24GHZ_BAND;
2569
2570 IPW_DEBUG_RX(
2571 "%s: '%s' frame type received (%d).\n",
2572 priv->net_dev->name, frame_types[frame_type],
2573 stats.len);
2574
2575 switch (frame_type) {
2576 case COMMAND_STATUS_VAL:
2577 /* Reset Rx watchdog */
2578 isr_rx_complete_command(
2579 priv, &u->rx_data.command);
2580 break;
2581
2582 case STATUS_CHANGE_VAL:
2583 isr_status_change(priv, u->rx_data.status);
2584 break;
2585
2586 case P80211_DATA_VAL:
2587 case P8023_DATA_VAL:
2588#ifdef CONFIG_IPW2100_MONITOR
2589 if (priv->ieee->iw_mode == IW_MODE_MONITOR) {
2590 isr_rx(priv, i, &stats);
2591 break;
2592 }
2593#endif
2594 if (stats.len < sizeof(u->rx_data.header))
2595 break;
2596 switch (WLAN_FC_GET_TYPE(u->rx_data.header.
2597 frame_ctl)) {
2598 case IEEE80211_FTYPE_MGMT:
2599 ieee80211_rx_mgt(priv->ieee,
2600 &u->rx_data.header,
2601 &stats);
2602 break;
2603
2604 case IEEE80211_FTYPE_CTL:
2605 break;
2606
2607 case IEEE80211_FTYPE_DATA:
2608 isr_rx(priv, i, &stats);
2609 break;
2610
2611 }
2612 break;
2613 }
2614
2615 increment:
2616 /* clear status field associated with this RBD */
2617 rxq->drv[i].status.info.field = 0;
2618
2619 i = (i + 1) % rxq->entries;
2620 }
2621
2622 if (i != s) {
2623 /* backtrack one entry, wrapping to end if at 0 */
2624 rxq->next = (i ? i : rxq->entries) - 1;
2625
2626 write_register(priv->net_dev,
2627 IPW_MEM_HOST_SHARED_RX_WRITE_INDEX,
2628 rxq->next);
2629 }
2630}
2631
2632
2633/*
2634 * __ipw2100_tx_process
2635 *
2636 * This routine will determine whether the next packet on
2637 * the fw_pend_list has been processed by the firmware yet.
2638 *
2639 * If not, then it does nothing and returns.
2640 *
2641 * If so, then it removes the item from the fw_pend_list, frees
2642 * any associated storage, and places the item back on the
2643 * free list of its source (either msg_free_list or tx_free_list)
2644 *
2645 * TX Queue works as follows:
2646 *
2647 * Read index - points to the next TBD that the firmware will
2648 * process. The firmware will read the data, and once
2649 * done processing, it will advance the Read index.
2650 *
2651 * Write index - driver fills this entry with an constructed TBD
2652 * entry. The Write index is not advanced until the
2653 * packet has been configured.
2654 *
2655 * In between the W and R indexes are the TBDs that have NOT been
2656 * processed. Lagging behind the R index are packets that have
2657 * been processed but have not been freed by the driver.
2658 *
2659 * In order to free old storage, an internal index will be maintained
2660 * that points to the next packet to be freed. When all used
2661 * packets have been freed, the oldest index will be the same as the
2662 * firmware's read index.
2663 *
2664 * The OLDEST index is cached in the variable 'priv->tx_queue.oldest'
2665 *
2666 * Because the TBD structure can not contain arbitrary data, the
2667 * driver must keep an internal queue of cached allocations such that
2668 * it can put that data back into the tx_free_list and msg_free_list
2669 * for use by future command and data packets.
2670 *
2671 */
2672static inline int __ipw2100_tx_process(struct ipw2100_priv *priv)
2673{
2674 struct ipw2100_bd_queue *txq = &priv->tx_queue;
2675 struct ipw2100_bd *tbd;
2676 struct list_head *element;
2677 struct ipw2100_tx_packet *packet;
2678 int descriptors_used;
2679 int e, i;
2680 u32 r, w, frag_num = 0;
2681
2682 if (list_empty(&priv->fw_pend_list))
2683 return 0;
2684
2685 element = priv->fw_pend_list.next;
2686
2687 packet = list_entry(element, struct ipw2100_tx_packet, list);
2688 tbd = &txq->drv[packet->index];
2689
2690 /* Determine how many TBD entries must be finished... */
2691 switch (packet->type) {
2692 case COMMAND:
2693 /* COMMAND uses only one slot; don't advance */
2694 descriptors_used = 1;
2695 e = txq->oldest;
2696 break;
2697
2698 case DATA:
2699 /* DATA uses two slots; advance and loop position. */
2700 descriptors_used = tbd->num_fragments;
2701 frag_num = tbd->num_fragments - 1;
2702 e = txq->oldest + frag_num;
2703 e %= txq->entries;
2704 break;
2705
2706 default:
2707 printk(KERN_WARNING DRV_NAME ": %s: Bad fw_pend_list entry!\n",
2708 priv->net_dev->name);
2709 return 0;
2710 }
2711
2712 /* if the last TBD is not done by NIC yet, then packet is
2713 * not ready to be released.
2714 *
2715 */
2716 read_register(priv->net_dev, IPW_MEM_HOST_SHARED_TX_QUEUE_READ_INDEX,
2717 &r);
2718 read_register(priv->net_dev, IPW_MEM_HOST_SHARED_TX_QUEUE_WRITE_INDEX,
2719 &w);
2720 if (w != txq->next)
2721 printk(KERN_WARNING DRV_NAME ": %s: write index mismatch\n",
2722 priv->net_dev->name);
2723
2724 /*
2725 * txq->next is the index of the last packet written txq->oldest is
2726 * the index of the r is the index of the next packet to be read by
2727 * firmware
2728 */
2729
2730
2731 /*
2732 * Quick graphic to help you visualize the following
2733 * if / else statement
2734 *
2735 * ===>| s---->|===============
2736 * e>|
2737 * | a | b | c | d | e | f | g | h | i | j | k | l
2738 * r---->|
2739 * w
2740 *
2741 * w - updated by driver
2742 * r - updated by firmware
2743 * s - start of oldest BD entry (txq->oldest)
2744 * e - end of oldest BD entry
2745 *
2746 */
2747 if (!((r <= w && (e < r || e >= w)) || (e < r && e >= w))) {
2748 IPW_DEBUG_TX("exit - no processed packets ready to release.\n");
2749 return 0;
2750 }
2751
2752 list_del(element);
2753 DEC_STAT(&priv->fw_pend_stat);
2754
2755#ifdef CONFIG_IPW_DEBUG
2756 {
2757 int i = txq->oldest;
2758 IPW_DEBUG_TX(
2759 "TX%d V=%p P=%04X T=%04X L=%d\n", i,
2760 &txq->drv[i],
2761 (u32)(txq->nic + i * sizeof(struct ipw2100_bd)),
2762 txq->drv[i].host_addr,
2763 txq->drv[i].buf_length);
2764
2765 if (packet->type == DATA) {
2766 i = (i + 1) % txq->entries;
2767
2768 IPW_DEBUG_TX(
2769 "TX%d V=%p P=%04X T=%04X L=%d\n", i,
2770 &txq->drv[i],
2771 (u32)(txq->nic + i *
2772 sizeof(struct ipw2100_bd)),
2773 (u32)txq->drv[i].host_addr,
2774 txq->drv[i].buf_length);
2775 }
2776 }
2777#endif
2778
2779 switch (packet->type) {
2780 case DATA:
2781 if (txq->drv[txq->oldest].status.info.fields.txType != 0)
2782 printk(KERN_WARNING DRV_NAME ": %s: Queue mismatch. "
2783 "Expecting DATA TBD but pulled "
2784 "something else: ids %d=%d.\n",
2785 priv->net_dev->name, txq->oldest, packet->index);
2786
2787 /* DATA packet; we have to unmap and free the SKB */
2788 priv->ieee->stats.tx_packets++;
2789 for (i = 0; i < frag_num; i++) {
2790 tbd = &txq->drv[(packet->index + 1 + i) %
2791 txq->entries];
2792
2793 IPW_DEBUG_TX(
2794 "TX%d P=%08x L=%d\n",
2795 (packet->index + 1 + i) % txq->entries,
2796 tbd->host_addr, tbd->buf_length);
2797
2798 pci_unmap_single(priv->pci_dev,
2799 tbd->host_addr,
2800 tbd->buf_length,
2801 PCI_DMA_TODEVICE);
2802 }
2803
2804 priv->ieee->stats.tx_bytes += packet->info.d_struct.txb->payload_size;
2805 ieee80211_txb_free(packet->info.d_struct.txb);
2806 packet->info.d_struct.txb = NULL;
2807
2808 list_add_tail(element, &priv->tx_free_list);
2809 INC_STAT(&priv->tx_free_stat);
2810
2811 /* We have a free slot in the Tx queue, so wake up the
2812 * transmit layer if it is stopped. */
2813 if (priv->status & STATUS_ASSOCIATED &&
2814 netif_queue_stopped(priv->net_dev)) {
2815 IPW_DEBUG_INFO(KERN_INFO
2816 "%s: Waking net queue.\n",
2817 priv->net_dev->name);
2818 netif_wake_queue(priv->net_dev);
2819 }
2820
2821 /* A packet was processed by the hardware, so update the
2822 * watchdog */
2823 priv->net_dev->trans_start = jiffies;
2824
2825 break;
2826
2827 case COMMAND:
2828 if (txq->drv[txq->oldest].status.info.fields.txType != 1)
2829 printk(KERN_WARNING DRV_NAME ": %s: Queue mismatch. "
2830 "Expecting COMMAND TBD but pulled "
2831 "something else: ids %d=%d.\n",
2832 priv->net_dev->name, txq->oldest, packet->index);
2833
2834#ifdef CONFIG_IPW_DEBUG
2835 if (packet->info.c_struct.cmd->host_command_reg <
2836 sizeof(command_types) / sizeof(*command_types))
2837 IPW_DEBUG_TX(
2838 "Command '%s (%d)' processed: %d.\n",
2839 command_types[packet->info.c_struct.cmd->host_command_reg],
2840 packet->info.c_struct.cmd->host_command_reg,
2841 packet->info.c_struct.cmd->cmd_status_reg);
2842#endif
2843
2844 list_add_tail(element, &priv->msg_free_list);
2845 INC_STAT(&priv->msg_free_stat);
2846 break;
2847 }
2848
2849 /* advance oldest used TBD pointer to start of next entry */
2850 txq->oldest = (e + 1) % txq->entries;
2851 /* increase available TBDs number */
2852 txq->available += descriptors_used;
2853 SET_STAT(&priv->txq_stat, txq->available);
2854
2855 IPW_DEBUG_TX("packet latency (send to process) %ld jiffies\n",
2856 jiffies - packet->jiffy_start);
2857
2858 return (!list_empty(&priv->fw_pend_list));
2859}
2860
2861
2862static inline void __ipw2100_tx_complete(struct ipw2100_priv *priv)
2863{
2864 int i = 0;
2865
2866 while (__ipw2100_tx_process(priv) && i < 200) i++;
2867
2868 if (i == 200) {
2869 printk(KERN_WARNING DRV_NAME ": "
2870 "%s: Driver is running slow (%d iters).\n",
2871 priv->net_dev->name, i);
2872 }
2873}
2874
2875
2876static void ipw2100_tx_send_commands(struct ipw2100_priv *priv)
2877{
2878 struct list_head *element;
2879 struct ipw2100_tx_packet *packet;
2880 struct ipw2100_bd_queue *txq = &priv->tx_queue;
2881 struct ipw2100_bd *tbd;
2882 int next = txq->next;
2883
2884 while (!list_empty(&priv->msg_pend_list)) {
2885 /* if there isn't enough space in TBD queue, then
2886 * don't stuff a new one in.
2887 * NOTE: 3 are needed as a command will take one,
2888 * and there is a minimum of 2 that must be
2889 * maintained between the r and w indexes
2890 */
2891 if (txq->available <= 3) {
2892 IPW_DEBUG_TX("no room in tx_queue\n");
2893 break;
2894 }
2895
2896 element = priv->msg_pend_list.next;
2897 list_del(element);
2898 DEC_STAT(&priv->msg_pend_stat);
2899
2900 packet = list_entry(element,
2901 struct ipw2100_tx_packet, list);
2902
2903 IPW_DEBUG_TX("using TBD at virt=%p, phys=%p\n",
2904 &txq->drv[txq->next],
2905 (void*)(txq->nic + txq->next *
2906 sizeof(struct ipw2100_bd)));
2907
2908 packet->index = txq->next;
2909
2910 tbd = &txq->drv[txq->next];
2911
2912 /* initialize TBD */
2913 tbd->host_addr = packet->info.c_struct.cmd_phys;
2914 tbd->buf_length = sizeof(struct ipw2100_cmd_header);
2915 /* not marking number of fragments causes problems
2916 * with f/w debug version */
2917 tbd->num_fragments = 1;
2918 tbd->status.info.field =
2919 IPW_BD_STATUS_TX_FRAME_COMMAND |
2920 IPW_BD_STATUS_TX_INTERRUPT_ENABLE;
2921
2922 /* update TBD queue counters */
2923 txq->next++;
2924 txq->next %= txq->entries;
2925 txq->available--;
2926 DEC_STAT(&priv->txq_stat);
2927
2928 list_add_tail(element, &priv->fw_pend_list);
2929 INC_STAT(&priv->fw_pend_stat);
2930 }
2931
2932 if (txq->next != next) {
2933 /* kick off the DMA by notifying firmware the
2934 * write index has moved; make sure TBD stores are sync'd */
2935 wmb();
2936 write_register(priv->net_dev,
2937 IPW_MEM_HOST_SHARED_TX_QUEUE_WRITE_INDEX,
2938 txq->next);
2939 }
2940}
2941
2942
2943/*
2944 * ipw2100_tx_send_data
2945 *
2946 */
2947static void ipw2100_tx_send_data(struct ipw2100_priv *priv)
2948{
2949 struct list_head *element;
2950 struct ipw2100_tx_packet *packet;
2951 struct ipw2100_bd_queue *txq = &priv->tx_queue;
2952 struct ipw2100_bd *tbd;
2953 int next = txq->next;
2954 int i = 0;
2955 struct ipw2100_data_header *ipw_hdr;
2956 struct ieee80211_hdr *hdr;
2957
2958 while (!list_empty(&priv->tx_pend_list)) {
2959 /* if there isn't enough space in TBD queue, then
2960 * don't stuff a new one in.
2961 * NOTE: 4 are needed as a data will take two,
2962 * and there is a minimum of 2 that must be
2963 * maintained between the r and w indexes
2964 */
2965 element = priv->tx_pend_list.next;
2966 packet = list_entry(element, struct ipw2100_tx_packet, list);
2967
2968 if (unlikely(1 + packet->info.d_struct.txb->nr_frags >
2969 IPW_MAX_BDS)) {
2970 /* TODO: Support merging buffers if more than
2971 * IPW_MAX_BDS are used */
2972 IPW_DEBUG_INFO(
2973 "%s: Maximum BD theshold exceeded. "
2974 "Increase fragmentation level.\n",
2975 priv->net_dev->name);
2976 }
2977
2978 if (txq->available <= 3 +
2979 packet->info.d_struct.txb->nr_frags) {
2980 IPW_DEBUG_TX("no room in tx_queue\n");
2981 break;
2982 }
2983
2984 list_del(element);
2985 DEC_STAT(&priv->tx_pend_stat);
2986
2987 tbd = &txq->drv[txq->next];
2988
2989 packet->index = txq->next;
2990
2991 ipw_hdr = packet->info.d_struct.data;
2992 hdr = (struct ieee80211_hdr *)packet->info.d_struct.txb->
2993 fragments[0]->data;
2994
2995 if (priv->ieee->iw_mode == IW_MODE_INFRA) {
2996 /* To DS: Addr1 = BSSID, Addr2 = SA,
2997 Addr3 = DA */
2998 memcpy(ipw_hdr->src_addr, hdr->addr2, ETH_ALEN);
2999 memcpy(ipw_hdr->dst_addr, hdr->addr3, ETH_ALEN);
3000 } else if (priv->ieee->iw_mode == IW_MODE_ADHOC) {
3001 /* not From/To DS: Addr1 = DA, Addr2 = SA,
3002 Addr3 = BSSID */
3003 memcpy(ipw_hdr->src_addr, hdr->addr2, ETH_ALEN);
3004 memcpy(ipw_hdr->dst_addr, hdr->addr1, ETH_ALEN);
3005 }
3006
3007 ipw_hdr->host_command_reg = SEND;
3008 ipw_hdr->host_command_reg1 = 0;
3009
3010 /* For now we only support host based encryption */
3011 ipw_hdr->needs_encryption = 0;
3012 ipw_hdr->encrypted = packet->info.d_struct.txb->encrypted;
3013 if (packet->info.d_struct.txb->nr_frags > 1)
3014 ipw_hdr->fragment_size =
3015 packet->info.d_struct.txb->frag_size - IEEE80211_3ADDR_LEN;
3016 else
3017 ipw_hdr->fragment_size = 0;
3018
3019 tbd->host_addr = packet->info.d_struct.data_phys;
3020 tbd->buf_length = sizeof(struct ipw2100_data_header);
3021 tbd->num_fragments = 1 + packet->info.d_struct.txb->nr_frags;
3022 tbd->status.info.field =
3023 IPW_BD_STATUS_TX_FRAME_802_3 |
3024 IPW_BD_STATUS_TX_FRAME_NOT_LAST_FRAGMENT;
3025 txq->next++;
3026 txq->next %= txq->entries;
3027
3028 IPW_DEBUG_TX(
3029 "data header tbd TX%d P=%08x L=%d\n",
3030 packet->index, tbd->host_addr,
3031 tbd->buf_length);
3032#ifdef CONFIG_IPW_DEBUG
3033 if (packet->info.d_struct.txb->nr_frags > 1)
3034 IPW_DEBUG_FRAG("fragment Tx: %d frames\n",
3035 packet->info.d_struct.txb->nr_frags);
3036#endif
3037
3038 for (i = 0; i < packet->info.d_struct.txb->nr_frags; i++) {
3039 tbd = &txq->drv[txq->next];
3040 if (i == packet->info.d_struct.txb->nr_frags - 1)
3041 tbd->status.info.field =
3042 IPW_BD_STATUS_TX_FRAME_802_3 |
3043 IPW_BD_STATUS_TX_INTERRUPT_ENABLE;
3044 else
3045 tbd->status.info.field =
3046 IPW_BD_STATUS_TX_FRAME_802_3 |
3047 IPW_BD_STATUS_TX_FRAME_NOT_LAST_FRAGMENT;
3048
3049 tbd->buf_length = packet->info.d_struct.txb->
3050 fragments[i]->len - IEEE80211_3ADDR_LEN;
3051
3052 tbd->host_addr = pci_map_single(
3053 priv->pci_dev,
3054 packet->info.d_struct.txb->fragments[i]->data +
3055 IEEE80211_3ADDR_LEN,
3056 tbd->buf_length,
3057 PCI_DMA_TODEVICE);
3058
3059 IPW_DEBUG_TX(
3060 "data frag tbd TX%d P=%08x L=%d\n",
3061 txq->next, tbd->host_addr, tbd->buf_length);
3062
3063 pci_dma_sync_single_for_device(
3064 priv->pci_dev, tbd->host_addr,
3065 tbd->buf_length,
3066 PCI_DMA_TODEVICE);
3067
3068 txq->next++;
3069 txq->next %= txq->entries;
3070 }
3071
3072 txq->available -= 1 + packet->info.d_struct.txb->nr_frags;
3073 SET_STAT(&priv->txq_stat, txq->available);
3074
3075 list_add_tail(element, &priv->fw_pend_list);
3076 INC_STAT(&priv->fw_pend_stat);
3077 }
3078
3079 if (txq->next != next) {
3080 /* kick off the DMA by notifying firmware the
3081 * write index has moved; make sure TBD stores are sync'd */
3082 write_register(priv->net_dev,
3083 IPW_MEM_HOST_SHARED_TX_QUEUE_WRITE_INDEX,
3084 txq->next);
3085 }
3086 return;
3087}
3088
3089static void ipw2100_irq_tasklet(struct ipw2100_priv *priv)
3090{
3091 struct net_device *dev = priv->net_dev;
3092 unsigned long flags;
3093 u32 inta, tmp;
3094
3095 spin_lock_irqsave(&priv->low_lock, flags);
3096 ipw2100_disable_interrupts(priv);
3097
3098 read_register(dev, IPW_REG_INTA, &inta);
3099
3100 IPW_DEBUG_ISR("enter - INTA: 0x%08lX\n",
3101 (unsigned long)inta & IPW_INTERRUPT_MASK);
3102
3103 priv->in_isr++;
3104 priv->interrupts++;
3105
3106 /* We do not loop and keep polling for more interrupts as this
3107 * is frowned upon and doesn't play nicely with other potentially
3108 * chained IRQs */
3109 IPW_DEBUG_ISR("INTA: 0x%08lX\n",
3110 (unsigned long)inta & IPW_INTERRUPT_MASK);
3111
3112 if (inta & IPW2100_INTA_FATAL_ERROR) {
3113 printk(KERN_WARNING DRV_NAME
3114 ": Fatal interrupt. Scheduling firmware restart.\n");
3115 priv->inta_other++;
3116 write_register(
3117 dev, IPW_REG_INTA,
3118 IPW2100_INTA_FATAL_ERROR);
3119
3120 read_nic_dword(dev, IPW_NIC_FATAL_ERROR, &priv->fatal_error);
3121 IPW_DEBUG_INFO("%s: Fatal error value: 0x%08X\n",
3122 priv->net_dev->name, priv->fatal_error);
3123
3124 read_nic_dword(dev, IPW_ERROR_ADDR(priv->fatal_error), &tmp);
3125 IPW_DEBUG_INFO("%s: Fatal error address value: 0x%08X\n",
3126 priv->net_dev->name, tmp);
3127
3128 /* Wake up any sleeping jobs */
3129 schedule_reset(priv);
3130 }
3131
3132 if (inta & IPW2100_INTA_PARITY_ERROR) {
3133 printk(KERN_ERR DRV_NAME ": ***** PARITY ERROR INTERRUPT !!!! \n");
3134 priv->inta_other++;
3135 write_register(
3136 dev, IPW_REG_INTA,
3137 IPW2100_INTA_PARITY_ERROR);
3138 }
3139
3140 if (inta & IPW2100_INTA_RX_TRANSFER) {
3141 IPW_DEBUG_ISR("RX interrupt\n");
3142
3143 priv->rx_interrupts++;
3144
3145 write_register(
3146 dev, IPW_REG_INTA,
3147 IPW2100_INTA_RX_TRANSFER);
3148
3149 __ipw2100_rx_process(priv);
3150 __ipw2100_tx_complete(priv);
3151 }
3152
3153 if (inta & IPW2100_INTA_TX_TRANSFER) {
3154 IPW_DEBUG_ISR("TX interrupt\n");
3155
3156 priv->tx_interrupts++;
3157
3158 write_register(dev, IPW_REG_INTA,
3159 IPW2100_INTA_TX_TRANSFER);
3160
3161 __ipw2100_tx_complete(priv);
3162 ipw2100_tx_send_commands(priv);
3163 ipw2100_tx_send_data(priv);
3164 }
3165
3166 if (inta & IPW2100_INTA_TX_COMPLETE) {
3167 IPW_DEBUG_ISR("TX complete\n");
3168 priv->inta_other++;
3169 write_register(
3170 dev, IPW_REG_INTA,
3171 IPW2100_INTA_TX_COMPLETE);
3172
3173 __ipw2100_tx_complete(priv);
3174 }
3175
3176 if (inta & IPW2100_INTA_EVENT_INTERRUPT) {
3177 /* ipw2100_handle_event(dev); */
3178 priv->inta_other++;
3179 write_register(
3180 dev, IPW_REG_INTA,
3181 IPW2100_INTA_EVENT_INTERRUPT);
3182 }
3183
3184 if (inta & IPW2100_INTA_FW_INIT_DONE) {
3185 IPW_DEBUG_ISR("FW init done interrupt\n");
3186 priv->inta_other++;
3187
3188 read_register(dev, IPW_REG_INTA, &tmp);
3189 if (tmp & (IPW2100_INTA_FATAL_ERROR |
3190 IPW2100_INTA_PARITY_ERROR)) {
3191 write_register(
3192 dev, IPW_REG_INTA,
3193 IPW2100_INTA_FATAL_ERROR |
3194 IPW2100_INTA_PARITY_ERROR);
3195 }
3196
3197 write_register(dev, IPW_REG_INTA,
3198 IPW2100_INTA_FW_INIT_DONE);
3199 }
3200
3201 if (inta & IPW2100_INTA_STATUS_CHANGE) {
3202 IPW_DEBUG_ISR("Status change interrupt\n");
3203 priv->inta_other++;
3204 write_register(
3205 dev, IPW_REG_INTA,
3206 IPW2100_INTA_STATUS_CHANGE);
3207 }
3208
3209 if (inta & IPW2100_INTA_SLAVE_MODE_HOST_COMMAND_DONE) {
3210 IPW_DEBUG_ISR("slave host mode interrupt\n");
3211 priv->inta_other++;
3212 write_register(
3213 dev, IPW_REG_INTA,
3214 IPW2100_INTA_SLAVE_MODE_HOST_COMMAND_DONE);
3215 }
3216
3217 priv->in_isr--;
3218 ipw2100_enable_interrupts(priv);
3219
3220 spin_unlock_irqrestore(&priv->low_lock, flags);
3221
3222 IPW_DEBUG_ISR("exit\n");
3223}
3224
3225
3226static irqreturn_t ipw2100_interrupt(int irq, void *data,
3227 struct pt_regs *regs)
3228{
3229 struct ipw2100_priv *priv = data;
3230 u32 inta, inta_mask;
3231
3232 if (!data)
3233 return IRQ_NONE;
3234
3235 spin_lock(&priv->low_lock);
3236
3237 /* We check to see if we should be ignoring interrupts before
3238 * we touch the hardware. During ucode load if we try and handle
3239 * an interrupt we can cause keyboard problems as well as cause
3240 * the ucode to fail to initialize */
3241 if (!(priv->status & STATUS_INT_ENABLED)) {
3242 /* Shared IRQ */
3243 goto none;
3244 }
3245
3246 read_register(priv->net_dev, IPW_REG_INTA_MASK, &inta_mask);
3247 read_register(priv->net_dev, IPW_REG_INTA, &inta);
3248
3249 if (inta == 0xFFFFFFFF) {
3250 /* Hardware disappeared */
3251 printk(KERN_WARNING DRV_NAME ": IRQ INTA == 0xFFFFFFFF\n");
3252 goto none;
3253 }
3254
3255 inta &= IPW_INTERRUPT_MASK;
3256
3257 if (!(inta & inta_mask)) {
3258 /* Shared interrupt */
3259 goto none;
3260 }
3261
3262 /* We disable the hardware interrupt here just to prevent unneeded
3263 * calls to be made. We disable this again within the actual
3264 * work tasklet, so if another part of the code re-enables the
3265 * interrupt, that is fine */
3266 ipw2100_disable_interrupts(priv);
3267
3268 tasklet_schedule(&priv->irq_tasklet);
3269 spin_unlock(&priv->low_lock);
3270
3271 return IRQ_HANDLED;
3272 none:
3273 spin_unlock(&priv->low_lock);
3274 return IRQ_NONE;
3275}
3276
3277static int ipw2100_tx(struct ieee80211_txb *txb, struct net_device *dev)
3278{
3279 struct ipw2100_priv *priv = ieee80211_priv(dev);
3280 struct list_head *element;
3281 struct ipw2100_tx_packet *packet;
3282 unsigned long flags;
3283
3284 spin_lock_irqsave(&priv->low_lock, flags);
3285
3286 if (!(priv->status & STATUS_ASSOCIATED)) {
3287 IPW_DEBUG_INFO("Can not transmit when not connected.\n");
3288 priv->ieee->stats.tx_carrier_errors++;
3289 netif_stop_queue(dev);
3290 goto fail_unlock;
3291 }
3292
3293 if (list_empty(&priv->tx_free_list))
3294 goto fail_unlock;
3295
3296 element = priv->tx_free_list.next;
3297 packet = list_entry(element, struct ipw2100_tx_packet, list);
3298
3299 packet->info.d_struct.txb = txb;
3300
3301 IPW_DEBUG_TX("Sending fragment (%d bytes):\n",
3302 txb->fragments[0]->len);
3303 printk_buf(IPW_DL_TX, txb->fragments[0]->data,
3304 txb->fragments[0]->len);
3305
3306 packet->jiffy_start = jiffies;
3307
3308 list_del(element);
3309 DEC_STAT(&priv->tx_free_stat);
3310
3311 list_add_tail(element, &priv->tx_pend_list);
3312 INC_STAT(&priv->tx_pend_stat);
3313
3314 ipw2100_tx_send_data(priv);
3315
3316 spin_unlock_irqrestore(&priv->low_lock, flags);
3317 return 0;
3318
3319 fail_unlock:
3320 netif_stop_queue(dev);
3321 spin_unlock_irqrestore(&priv->low_lock, flags);
3322 return 1;
3323}
3324
3325
3326static int ipw2100_msg_allocate(struct ipw2100_priv *priv)
3327{
3328 int i, j, err = -EINVAL;
3329 void *v;
3330 dma_addr_t p;
3331
3332 priv->msg_buffers = (struct ipw2100_tx_packet *)kmalloc(
3333 IPW_COMMAND_POOL_SIZE * sizeof(struct ipw2100_tx_packet),
3334 GFP_KERNEL);
3335 if (!priv->msg_buffers) {
3336 printk(KERN_ERR DRV_NAME ": %s: PCI alloc failed for msg "
3337 "buffers.\n", priv->net_dev->name);
3338 return -ENOMEM;
3339 }
3340
3341 for (i = 0; i < IPW_COMMAND_POOL_SIZE; i++) {
3342 v = pci_alloc_consistent(
3343 priv->pci_dev,
3344 sizeof(struct ipw2100_cmd_header),
3345 &p);
3346 if (!v) {
3347 printk(KERN_ERR DRV_NAME ": "
3348 "%s: PCI alloc failed for msg "
3349 "buffers.\n",
3350 priv->net_dev->name);
3351 err = -ENOMEM;
3352 break;
3353 }
3354
3355 memset(v, 0, sizeof(struct ipw2100_cmd_header));
3356
3357 priv->msg_buffers[i].type = COMMAND;
3358 priv->msg_buffers[i].info.c_struct.cmd =
3359 (struct ipw2100_cmd_header*)v;
3360 priv->msg_buffers[i].info.c_struct.cmd_phys = p;
3361 }
3362
3363 if (i == IPW_COMMAND_POOL_SIZE)
3364 return 0;
3365
3366 for (j = 0; j < i; j++) {
3367 pci_free_consistent(
3368 priv->pci_dev,
3369 sizeof(struct ipw2100_cmd_header),
3370 priv->msg_buffers[j].info.c_struct.cmd,
3371 priv->msg_buffers[j].info.c_struct.cmd_phys);
3372 }
3373
3374 kfree(priv->msg_buffers);
3375 priv->msg_buffers = NULL;
3376
3377 return err;
3378}
3379
3380static int ipw2100_msg_initialize(struct ipw2100_priv *priv)
3381{
3382 int i;
3383
3384 INIT_LIST_HEAD(&priv->msg_free_list);
3385 INIT_LIST_HEAD(&priv->msg_pend_list);
3386
3387 for (i = 0; i < IPW_COMMAND_POOL_SIZE; i++)
3388 list_add_tail(&priv->msg_buffers[i].list, &priv->msg_free_list);
3389 SET_STAT(&priv->msg_free_stat, i);
3390
3391 return 0;
3392}
3393
3394static void ipw2100_msg_free(struct ipw2100_priv *priv)
3395{
3396 int i;
3397
3398 if (!priv->msg_buffers)
3399 return;
3400
3401 for (i = 0; i < IPW_COMMAND_POOL_SIZE; i++) {
3402 pci_free_consistent(priv->pci_dev,
3403 sizeof(struct ipw2100_cmd_header),
3404 priv->msg_buffers[i].info.c_struct.cmd,
3405 priv->msg_buffers[i].info.c_struct.cmd_phys);
3406 }
3407
3408 kfree(priv->msg_buffers);
3409 priv->msg_buffers = NULL;
3410}
3411
3412static ssize_t show_pci(struct device *d, struct device_attribute *attr,
3413 char *buf)
3414{
3415 struct pci_dev *pci_dev = container_of(d, struct pci_dev, dev);
3416 char *out = buf;
3417 int i, j;
3418 u32 val;
3419
3420 for (i = 0; i < 16; i++) {
3421 out += sprintf(out, "[%08X] ", i * 16);
3422 for (j = 0; j < 16; j += 4) {
3423 pci_read_config_dword(pci_dev, i * 16 + j, &val);
3424 out += sprintf(out, "%08X ", val);
3425 }
3426 out += sprintf(out, "\n");
3427 }
3428
3429 return out - buf;
3430}
3431static DEVICE_ATTR(pci, S_IRUGO, show_pci, NULL);
3432
3433static ssize_t show_cfg(struct device *d, struct device_attribute *attr,
3434 char *buf)
3435{
3436 struct ipw2100_priv *p = d->driver_data;
3437 return sprintf(buf, "0x%08x\n", (int)p->config);
3438}
3439static DEVICE_ATTR(cfg, S_IRUGO, show_cfg, NULL);
3440
3441static ssize_t show_status(struct device *d, struct device_attribute *attr,
3442 char *buf)
3443{
3444 struct ipw2100_priv *p = d->driver_data;
3445 return sprintf(buf, "0x%08x\n", (int)p->status);
3446}
3447static DEVICE_ATTR(status, S_IRUGO, show_status, NULL);
3448
3449static ssize_t show_capability(struct device *d, struct device_attribute *attr,
3450 char *buf)
3451{
3452 struct ipw2100_priv *p = d->driver_data;
3453 return sprintf(buf, "0x%08x\n", (int)p->capability);
3454}
3455static DEVICE_ATTR(capability, S_IRUGO, show_capability, NULL);
3456
3457
3458#define IPW2100_REG(x) { IPW_ ##x, #x }
3459static const struct {
3460 u32 addr;
3461 const char *name;
3462} hw_data[] = {
3463 IPW2100_REG(REG_GP_CNTRL),
3464 IPW2100_REG(REG_GPIO),
3465 IPW2100_REG(REG_INTA),
3466 IPW2100_REG(REG_INTA_MASK),
3467 IPW2100_REG(REG_RESET_REG),
3468};
3469#define IPW2100_NIC(x, s) { x, #x, s }
3470static const struct {
3471 u32 addr;
3472 const char *name;
3473 size_t size;
3474} nic_data[] = {
3475 IPW2100_NIC(IPW2100_CONTROL_REG, 2),
3476 IPW2100_NIC(0x210014, 1),
3477 IPW2100_NIC(0x210000, 1),
3478};
3479#define IPW2100_ORD(x, d) { IPW_ORD_ ##x, #x, d }
3480static const struct {
3481 u8 index;
3482 const char *name;
3483 const char *desc;
3484} ord_data[] = {
3485 IPW2100_ORD(STAT_TX_HOST_REQUESTS, "requested Host Tx's (MSDU)"),
3486 IPW2100_ORD(STAT_TX_HOST_COMPLETE, "successful Host Tx's (MSDU)"),
3487 IPW2100_ORD(STAT_TX_DIR_DATA, "successful Directed Tx's (MSDU)"),
3488 IPW2100_ORD(STAT_TX_DIR_DATA1, "successful Directed Tx's (MSDU) @ 1MB"),
3489 IPW2100_ORD(STAT_TX_DIR_DATA2, "successful Directed Tx's (MSDU) @ 2MB"),
3490 IPW2100_ORD(STAT_TX_DIR_DATA5_5, "successful Directed Tx's (MSDU) @ 5_5MB"),
3491 IPW2100_ORD(STAT_TX_DIR_DATA11, "successful Directed Tx's (MSDU) @ 11MB"),
3492 IPW2100_ORD(STAT_TX_NODIR_DATA1, "successful Non_Directed Tx's (MSDU) @ 1MB"),
3493 IPW2100_ORD(STAT_TX_NODIR_DATA2, "successful Non_Directed Tx's (MSDU) @ 2MB"),
3494 IPW2100_ORD(STAT_TX_NODIR_DATA5_5, "successful Non_Directed Tx's (MSDU) @ 5.5MB"),
3495 IPW2100_ORD(STAT_TX_NODIR_DATA11, "successful Non_Directed Tx's (MSDU) @ 11MB"),
3496 IPW2100_ORD(STAT_NULL_DATA, "successful NULL data Tx's"),
3497 IPW2100_ORD(STAT_TX_RTS, "successful Tx RTS"),
3498 IPW2100_ORD(STAT_TX_CTS, "successful Tx CTS"),
3499 IPW2100_ORD(STAT_TX_ACK, "successful Tx ACK"),
3500 IPW2100_ORD(STAT_TX_ASSN, "successful Association Tx's"),
3501 IPW2100_ORD(STAT_TX_ASSN_RESP, "successful Association response Tx's"),
3502 IPW2100_ORD(STAT_TX_REASSN, "successful Reassociation Tx's"),
3503 IPW2100_ORD(STAT_TX_REASSN_RESP, "successful Reassociation response Tx's"),
3504 IPW2100_ORD(STAT_TX_PROBE, "probes successfully transmitted"),
3505 IPW2100_ORD(STAT_TX_PROBE_RESP, "probe responses successfully transmitted"),
3506 IPW2100_ORD(STAT_TX_BEACON, "tx beacon"),
3507 IPW2100_ORD(STAT_TX_ATIM, "Tx ATIM"),
3508 IPW2100_ORD(STAT_TX_DISASSN, "successful Disassociation TX"),
3509 IPW2100_ORD(STAT_TX_AUTH, "successful Authentication Tx"),
3510 IPW2100_ORD(STAT_TX_DEAUTH, "successful Deauthentication TX"),
3511 IPW2100_ORD(STAT_TX_TOTAL_BYTES, "Total successful Tx data bytes"),
3512 IPW2100_ORD(STAT_TX_RETRIES, "Tx retries"),
3513 IPW2100_ORD(STAT_TX_RETRY1, "Tx retries at 1MBPS"),
3514 IPW2100_ORD(STAT_TX_RETRY2, "Tx retries at 2MBPS"),
3515 IPW2100_ORD(STAT_TX_RETRY5_5, "Tx retries at 5.5MBPS"),
3516 IPW2100_ORD(STAT_TX_RETRY11, "Tx retries at 11MBPS"),
3517 IPW2100_ORD(STAT_TX_FAILURES, "Tx Failures"),
3518 IPW2100_ORD(STAT_TX_MAX_TRIES_IN_HOP,"times max tries in a hop failed"),
3519 IPW2100_ORD(STAT_TX_DISASSN_FAIL, "times disassociation failed"),
3520 IPW2100_ORD(STAT_TX_ERR_CTS, "missed/bad CTS frames"),
3521 IPW2100_ORD(STAT_TX_ERR_ACK, "tx err due to acks"),
3522 IPW2100_ORD(STAT_RX_HOST, "packets passed to host"),
3523 IPW2100_ORD(STAT_RX_DIR_DATA, "directed packets"),
3524 IPW2100_ORD(STAT_RX_DIR_DATA1, "directed packets at 1MB"),
3525 IPW2100_ORD(STAT_RX_DIR_DATA2, "directed packets at 2MB"),
3526 IPW2100_ORD(STAT_RX_DIR_DATA5_5, "directed packets at 5.5MB"),
3527 IPW2100_ORD(STAT_RX_DIR_DATA11, "directed packets at 11MB"),
3528 IPW2100_ORD(STAT_RX_NODIR_DATA,"nondirected packets"),
3529 IPW2100_ORD(STAT_RX_NODIR_DATA1, "nondirected packets at 1MB"),
3530 IPW2100_ORD(STAT_RX_NODIR_DATA2, "nondirected packets at 2MB"),
3531 IPW2100_ORD(STAT_RX_NODIR_DATA5_5, "nondirected packets at 5.5MB"),
3532 IPW2100_ORD(STAT_RX_NODIR_DATA11, "nondirected packets at 11MB"),
3533 IPW2100_ORD(STAT_RX_NULL_DATA, "null data rx's"),
3534 IPW2100_ORD(STAT_RX_RTS, "Rx RTS"),
3535 IPW2100_ORD(STAT_RX_CTS, "Rx CTS"),
3536 IPW2100_ORD(STAT_RX_ACK, "Rx ACK"),
3537 IPW2100_ORD(STAT_RX_CFEND, "Rx CF End"),
3538 IPW2100_ORD(STAT_RX_CFEND_ACK, "Rx CF End + CF Ack"),
3539 IPW2100_ORD(STAT_RX_ASSN, "Association Rx's"),
3540 IPW2100_ORD(STAT_RX_ASSN_RESP, "Association response Rx's"),
3541 IPW2100_ORD(STAT_RX_REASSN, "Reassociation Rx's"),
3542 IPW2100_ORD(STAT_RX_REASSN_RESP, "Reassociation response Rx's"),
3543 IPW2100_ORD(STAT_RX_PROBE, "probe Rx's"),
3544 IPW2100_ORD(STAT_RX_PROBE_RESP, "probe response Rx's"),
3545 IPW2100_ORD(STAT_RX_BEACON, "Rx beacon"),
3546 IPW2100_ORD(STAT_RX_ATIM, "Rx ATIM"),
3547 IPW2100_ORD(STAT_RX_DISASSN, "disassociation Rx"),
3548 IPW2100_ORD(STAT_RX_AUTH, "authentication Rx"),
3549 IPW2100_ORD(STAT_RX_DEAUTH, "deauthentication Rx"),
3550 IPW2100_ORD(STAT_RX_TOTAL_BYTES,"Total rx data bytes received"),
3551 IPW2100_ORD(STAT_RX_ERR_CRC, "packets with Rx CRC error"),
3552 IPW2100_ORD(STAT_RX_ERR_CRC1, "Rx CRC errors at 1MB"),
3553 IPW2100_ORD(STAT_RX_ERR_CRC2, "Rx CRC errors at 2MB"),
3554 IPW2100_ORD(STAT_RX_ERR_CRC5_5, "Rx CRC errors at 5.5MB"),
3555 IPW2100_ORD(STAT_RX_ERR_CRC11, "Rx CRC errors at 11MB"),
3556 IPW2100_ORD(STAT_RX_DUPLICATE1, "duplicate rx packets at 1MB"),
3557 IPW2100_ORD(STAT_RX_DUPLICATE2, "duplicate rx packets at 2MB"),
3558 IPW2100_ORD(STAT_RX_DUPLICATE5_5, "duplicate rx packets at 5.5MB"),
3559 IPW2100_ORD(STAT_RX_DUPLICATE11, "duplicate rx packets at 11MB"),
3560 IPW2100_ORD(STAT_RX_DUPLICATE, "duplicate rx packets"),
3561 IPW2100_ORD(PERS_DB_LOCK, "locking fw permanent db"),
3562 IPW2100_ORD(PERS_DB_SIZE, "size of fw permanent db"),
3563 IPW2100_ORD(PERS_DB_ADDR, "address of fw permanent db"),
3564 IPW2100_ORD(STAT_RX_INVALID_PROTOCOL, "rx frames with invalid protocol"),
3565 IPW2100_ORD(SYS_BOOT_TIME, "Boot time"),
3566 IPW2100_ORD(STAT_RX_NO_BUFFER, "rx frames rejected due to no buffer"),
3567 IPW2100_ORD(STAT_RX_MISSING_FRAG, "rx frames dropped due to missing fragment"),
3568 IPW2100_ORD(STAT_RX_ORPHAN_FRAG, "rx frames dropped due to non-sequential fragment"),
3569 IPW2100_ORD(STAT_RX_ORPHAN_FRAME, "rx frames dropped due to unmatched 1st frame"),
3570 IPW2100_ORD(STAT_RX_FRAG_AGEOUT, "rx frames dropped due to uncompleted frame"),
3571 IPW2100_ORD(STAT_RX_ICV_ERRORS, "ICV errors during decryption"),
3572 IPW2100_ORD(STAT_PSP_SUSPENSION,"times adapter suspended"),
3573 IPW2100_ORD(STAT_PSP_BCN_TIMEOUT, "beacon timeout"),
3574 IPW2100_ORD(STAT_PSP_POLL_TIMEOUT, "poll response timeouts"),
3575 IPW2100_ORD(STAT_PSP_NONDIR_TIMEOUT, "timeouts waiting for last {broad,multi}cast pkt"),
3576 IPW2100_ORD(STAT_PSP_RX_DTIMS, "PSP DTIMs received"),
3577 IPW2100_ORD(STAT_PSP_RX_TIMS, "PSP TIMs received"),
3578 IPW2100_ORD(STAT_PSP_STATION_ID,"PSP Station ID"),
3579 IPW2100_ORD(LAST_ASSN_TIME, "RTC time of last association"),
3580 IPW2100_ORD(STAT_PERCENT_MISSED_BCNS,"current calculation of % missed beacons"),
3581 IPW2100_ORD(STAT_PERCENT_RETRIES,"current calculation of % missed tx retries"),
3582 IPW2100_ORD(ASSOCIATED_AP_PTR, "0 if not associated, else pointer to AP table entry"),
3583 IPW2100_ORD(AVAILABLE_AP_CNT, "AP's decsribed in the AP table"),
3584 IPW2100_ORD(AP_LIST_PTR, "Ptr to list of available APs"),
3585 IPW2100_ORD(STAT_AP_ASSNS, "associations"),
3586 IPW2100_ORD(STAT_ASSN_FAIL, "association failures"),
3587 IPW2100_ORD(STAT_ASSN_RESP_FAIL,"failures due to response fail"),
3588 IPW2100_ORD(STAT_FULL_SCANS, "full scans"),
3589 IPW2100_ORD(CARD_DISABLED, "Card Disabled"),
3590 IPW2100_ORD(STAT_ROAM_INHIBIT, "times roaming was inhibited due to activity"),
3591 IPW2100_ORD(RSSI_AT_ASSN, "RSSI of associated AP at time of association"),
3592 IPW2100_ORD(STAT_ASSN_CAUSE1, "reassociation: no probe response or TX on hop"),
3593 IPW2100_ORD(STAT_ASSN_CAUSE2, "reassociation: poor tx/rx quality"),
3594 IPW2100_ORD(STAT_ASSN_CAUSE3, "reassociation: tx/rx quality (excessive AP load"),
3595 IPW2100_ORD(STAT_ASSN_CAUSE4, "reassociation: AP RSSI level"),
3596 IPW2100_ORD(STAT_ASSN_CAUSE5, "reassociations due to load leveling"),
3597 IPW2100_ORD(STAT_AUTH_FAIL, "times authentication failed"),
3598 IPW2100_ORD(STAT_AUTH_RESP_FAIL,"times authentication response failed"),
3599 IPW2100_ORD(STATION_TABLE_CNT, "entries in association table"),
3600 IPW2100_ORD(RSSI_AVG_CURR, "Current avg RSSI"),
3601 IPW2100_ORD(POWER_MGMT_MODE, "Power mode - 0=CAM, 1=PSP"),
3602 IPW2100_ORD(COUNTRY_CODE, "IEEE country code as recv'd from beacon"),
3603 IPW2100_ORD(COUNTRY_CHANNELS, "channels suported by country"),
3604 IPW2100_ORD(RESET_CNT, "adapter resets (warm)"),
3605 IPW2100_ORD(BEACON_INTERVAL, "Beacon interval"),
3606 IPW2100_ORD(ANTENNA_DIVERSITY, "TRUE if antenna diversity is disabled"),
3607 IPW2100_ORD(DTIM_PERIOD, "beacon intervals between DTIMs"),
3608 IPW2100_ORD(OUR_FREQ, "current radio freq lower digits - channel ID"),
3609 IPW2100_ORD(RTC_TIME, "current RTC time"),
3610 IPW2100_ORD(PORT_TYPE, "operating mode"),
3611 IPW2100_ORD(CURRENT_TX_RATE, "current tx rate"),
3612 IPW2100_ORD(SUPPORTED_RATES, "supported tx rates"),
3613 IPW2100_ORD(ATIM_WINDOW, "current ATIM Window"),
3614 IPW2100_ORD(BASIC_RATES, "basic tx rates"),
3615 IPW2100_ORD(NIC_HIGHEST_RATE, "NIC highest tx rate"),
3616 IPW2100_ORD(AP_HIGHEST_RATE, "AP highest tx rate"),
3617 IPW2100_ORD(CAPABILITIES, "Management frame capability field"),
3618 IPW2100_ORD(AUTH_TYPE, "Type of authentication"),
3619 IPW2100_ORD(RADIO_TYPE, "Adapter card platform type"),
3620 IPW2100_ORD(RTS_THRESHOLD, "Min packet length for RTS handshaking"),
3621 IPW2100_ORD(INT_MODE, "International mode"),
3622 IPW2100_ORD(FRAGMENTATION_THRESHOLD, "protocol frag threshold"),
3623 IPW2100_ORD(EEPROM_SRAM_DB_BLOCK_START_ADDRESS, "EEPROM offset in SRAM"),
3624 IPW2100_ORD(EEPROM_SRAM_DB_BLOCK_SIZE, "EEPROM size in SRAM"),
3625 IPW2100_ORD(EEPROM_SKU_CAPABILITY, "EEPROM SKU Capability"),
3626 IPW2100_ORD(EEPROM_IBSS_11B_CHANNELS, "EEPROM IBSS 11b channel set"),
3627 IPW2100_ORD(MAC_VERSION, "MAC Version"),
3628 IPW2100_ORD(MAC_REVISION, "MAC Revision"),
3629 IPW2100_ORD(RADIO_VERSION, "Radio Version"),
3630 IPW2100_ORD(NIC_MANF_DATE_TIME, "MANF Date/Time STAMP"),
3631 IPW2100_ORD(UCODE_VERSION, "Ucode Version"),
3632};
3633
3634
3635static ssize_t show_registers(struct device *d, struct device_attribute *attr,
3636 char *buf)
3637{
3638 int i;
3639 struct ipw2100_priv *priv = dev_get_drvdata(d);
3640 struct net_device *dev = priv->net_dev;
3641 char * out = buf;
3642 u32 val = 0;
3643
3644 out += sprintf(out, "%30s [Address ] : Hex\n", "Register");
3645
3646 for (i = 0; i < (sizeof(hw_data) / sizeof(*hw_data)); i++) {
3647 read_register(dev, hw_data[i].addr, &val);
3648 out += sprintf(out, "%30s [%08X] : %08X\n",
3649 hw_data[i].name, hw_data[i].addr, val);
3650 }
3651
3652 return out - buf;
3653}
3654static DEVICE_ATTR(registers, S_IRUGO, show_registers, NULL);
3655
3656
3657static ssize_t show_hardware(struct device *d, struct device_attribute *attr,
3658 char *buf)
3659{
3660 struct ipw2100_priv *priv = dev_get_drvdata(d);
3661 struct net_device *dev = priv->net_dev;
3662 char * out = buf;
3663 int i;
3664
3665 out += sprintf(out, "%30s [Address ] : Hex\n", "NIC entry");
3666
3667 for (i = 0; i < (sizeof(nic_data) / sizeof(*nic_data)); i++) {
3668 u8 tmp8;
3669 u16 tmp16;
3670 u32 tmp32;
3671
3672 switch (nic_data[i].size) {
3673 case 1:
3674 read_nic_byte(dev, nic_data[i].addr, &tmp8);
3675 out += sprintf(out, "%30s [%08X] : %02X\n",
3676 nic_data[i].name, nic_data[i].addr,
3677 tmp8);
3678 break;
3679 case 2:
3680 read_nic_word(dev, nic_data[i].addr, &tmp16);
3681 out += sprintf(out, "%30s [%08X] : %04X\n",
3682 nic_data[i].name, nic_data[i].addr,
3683 tmp16);
3684 break;
3685 case 4:
3686 read_nic_dword(dev, nic_data[i].addr, &tmp32);
3687 out += sprintf(out, "%30s [%08X] : %08X\n",
3688 nic_data[i].name, nic_data[i].addr,
3689 tmp32);
3690 break;
3691 }
3692 }
3693 return out - buf;
3694}
3695static DEVICE_ATTR(hardware, S_IRUGO, show_hardware, NULL);
3696
3697
3698static ssize_t show_memory(struct device *d, struct device_attribute *attr,
3699 char *buf)
3700{
3701 struct ipw2100_priv *priv = dev_get_drvdata(d);
3702 struct net_device *dev = priv->net_dev;
3703 static unsigned long loop = 0;
3704 int len = 0;
3705 u32 buffer[4];
3706 int i;
3707 char line[81];
3708
3709 if (loop >= 0x30000)
3710 loop = 0;
3711
3712 /* sysfs provides us PAGE_SIZE buffer */
3713 while (len < PAGE_SIZE - 128 && loop < 0x30000) {
3714
3715 if (priv->snapshot[0]) for (i = 0; i < 4; i++)
3716 buffer[i] = *(u32 *)SNAPSHOT_ADDR(loop + i * 4);
3717 else for (i = 0; i < 4; i++)
3718 read_nic_dword(dev, loop + i * 4, &buffer[i]);
3719
3720 if (priv->dump_raw)
3721 len += sprintf(buf + len,
3722 "%c%c%c%c"
3723 "%c%c%c%c"
3724 "%c%c%c%c"
3725 "%c%c%c%c",
3726 ((u8*)buffer)[0x0],
3727 ((u8*)buffer)[0x1],
3728 ((u8*)buffer)[0x2],
3729 ((u8*)buffer)[0x3],
3730 ((u8*)buffer)[0x4],
3731 ((u8*)buffer)[0x5],
3732 ((u8*)buffer)[0x6],
3733 ((u8*)buffer)[0x7],
3734 ((u8*)buffer)[0x8],
3735 ((u8*)buffer)[0x9],
3736 ((u8*)buffer)[0xa],
3737 ((u8*)buffer)[0xb],
3738 ((u8*)buffer)[0xc],
3739 ((u8*)buffer)[0xd],
3740 ((u8*)buffer)[0xe],
3741 ((u8*)buffer)[0xf]);
3742 else
3743 len += sprintf(buf + len, "%s\n",
3744 snprint_line(line, sizeof(line),
3745 (u8*)buffer, 16, loop));
3746 loop += 16;
3747 }
3748
3749 return len;
3750}
3751
3752static ssize_t store_memory(struct device *d, struct device_attribute *attr,
3753 const char *buf, size_t count)
3754{
3755 struct ipw2100_priv *priv = dev_get_drvdata(d);
3756 struct net_device *dev = priv->net_dev;
3757 const char *p = buf;
3758
3759 if (count < 1)
3760 return count;
3761
3762 if (p[0] == '1' ||
3763 (count >= 2 && tolower(p[0]) == 'o' && tolower(p[1]) == 'n')) {
3764 IPW_DEBUG_INFO("%s: Setting memory dump to RAW mode.\n",
3765 dev->name);
3766 priv->dump_raw = 1;
3767
3768 } else if (p[0] == '0' || (count >= 2 && tolower(p[0]) == 'o' &&
3769 tolower(p[1]) == 'f')) {
3770 IPW_DEBUG_INFO("%s: Setting memory dump to HEX mode.\n",
3771 dev->name);
3772 priv->dump_raw = 0;
3773
3774 } else if (tolower(p[0]) == 'r') {
3775 IPW_DEBUG_INFO("%s: Resetting firmware snapshot.\n",
3776 dev->name);
3777 ipw2100_snapshot_free(priv);
3778
3779 } else
3780 IPW_DEBUG_INFO("%s: Usage: 0|on = HEX, 1|off = RAW, "
3781 "reset = clear memory snapshot\n",
3782 dev->name);
3783
3784 return count;
3785}
3786static DEVICE_ATTR(memory, S_IWUSR|S_IRUGO, show_memory, store_memory);
3787
3788
3789static ssize_t show_ordinals(struct device *d, struct device_attribute *attr,
3790 char *buf)
3791{
3792 struct ipw2100_priv *priv = dev_get_drvdata(d);
3793 u32 val = 0;
3794 int len = 0;
3795 u32 val_len;
3796 static int loop = 0;
3797
3798 if (loop >= sizeof(ord_data) / sizeof(*ord_data))
3799 loop = 0;
3800
3801 /* sysfs provides us PAGE_SIZE buffer */
3802 while (len < PAGE_SIZE - 128 &&
3803 loop < (sizeof(ord_data) / sizeof(*ord_data))) {
3804
3805 val_len = sizeof(u32);
3806
3807 if (ipw2100_get_ordinal(priv, ord_data[loop].index, &val,
3808 &val_len))
3809 len += sprintf(buf + len, "[0x%02X] = ERROR %s\n",
3810 ord_data[loop].index,
3811 ord_data[loop].desc);
3812 else
3813 len += sprintf(buf + len, "[0x%02X] = 0x%08X %s\n",
3814 ord_data[loop].index, val,
3815 ord_data[loop].desc);
3816 loop++;
3817 }
3818
3819 return len;
3820}
3821static DEVICE_ATTR(ordinals, S_IRUGO, show_ordinals, NULL);
3822
3823
3824static ssize_t show_stats(struct device *d, struct device_attribute *attr,
3825 char *buf)
3826{
3827 struct ipw2100_priv *priv = dev_get_drvdata(d);
3828 char * out = buf;
3829
3830 out += sprintf(out, "interrupts: %d {tx: %d, rx: %d, other: %d}\n",
3831 priv->interrupts, priv->tx_interrupts,
3832 priv->rx_interrupts, priv->inta_other);
3833 out += sprintf(out, "firmware resets: %d\n", priv->resets);
3834 out += sprintf(out, "firmware hangs: %d\n", priv->hangs);
3835#ifdef CONFIG_IPW_DEBUG
3836 out += sprintf(out, "packet mismatch image: %s\n",
3837 priv->snapshot[0] ? "YES" : "NO");
3838#endif
3839
3840 return out - buf;
3841}
3842static DEVICE_ATTR(stats, S_IRUGO, show_stats, NULL);
3843
3844
3845static int ipw2100_switch_mode(struct ipw2100_priv *priv, u32 mode)
3846{
3847 int err;
3848
3849 if (mode == priv->ieee->iw_mode)
3850 return 0;
3851
3852 err = ipw2100_disable_adapter(priv);
3853 if (err) {
3854 printk(KERN_ERR DRV_NAME ": %s: Could not disable adapter %d\n",
3855 priv->net_dev->name, err);
3856 return err;
3857 }
3858
3859 switch (mode) {
3860 case IW_MODE_INFRA:
3861 priv->net_dev->type = ARPHRD_ETHER;
3862 break;
3863 case IW_MODE_ADHOC:
3864 priv->net_dev->type = ARPHRD_ETHER;
3865 break;
3866#ifdef CONFIG_IPW2100_MONITOR
3867 case IW_MODE_MONITOR:
3868 priv->last_mode = priv->ieee->iw_mode;
3869 priv->net_dev->type = ARPHRD_IEEE80211;
3870 break;
3871#endif /* CONFIG_IPW2100_MONITOR */
3872 }
3873
3874 priv->ieee->iw_mode = mode;
3875
3876#ifdef CONFIG_PM
3877 /* Indicate ipw2100_download_firmware download firmware
3878 * from disk instead of memory. */
3879 ipw2100_firmware.version = 0;
3880#endif
3881
3882 printk(KERN_INFO "%s: Reseting on mode change.\n",
3883 priv->net_dev->name);
3884 priv->reset_backoff = 0;
3885 schedule_reset(priv);
3886
3887 return 0;
3888}
3889
3890static ssize_t show_internals(struct device *d, struct device_attribute *attr,
3891 char *buf)
3892{
3893 struct ipw2100_priv *priv = dev_get_drvdata(d);
3894 int len = 0;
3895
3896#define DUMP_VAR(x,y) len += sprintf(buf + len, # x ": %" # y "\n", priv-> x)
3897
3898 if (priv->status & STATUS_ASSOCIATED)
3899 len += sprintf(buf + len, "connected: %lu\n",
3900 get_seconds() - priv->connect_start);
3901 else
3902 len += sprintf(buf + len, "not connected\n");
3903
3904 DUMP_VAR(ieee->crypt[priv->ieee->tx_keyidx], p);
3905 DUMP_VAR(status, 08lx);
3906 DUMP_VAR(config, 08lx);
3907 DUMP_VAR(capability, 08lx);
3908
3909 len += sprintf(buf + len, "last_rtc: %lu\n", (unsigned long)priv->last_rtc);
3910
3911 DUMP_VAR(fatal_error, d);
3912 DUMP_VAR(stop_hang_check, d);
3913 DUMP_VAR(stop_rf_kill, d);
3914 DUMP_VAR(messages_sent, d);
3915
3916 DUMP_VAR(tx_pend_stat.value, d);
3917 DUMP_VAR(tx_pend_stat.hi, d);
3918
3919 DUMP_VAR(tx_free_stat.value, d);
3920 DUMP_VAR(tx_free_stat.lo, d);
3921
3922 DUMP_VAR(msg_free_stat.value, d);
3923 DUMP_VAR(msg_free_stat.lo, d);
3924
3925 DUMP_VAR(msg_pend_stat.value, d);
3926 DUMP_VAR(msg_pend_stat.hi, d);
3927
3928 DUMP_VAR(fw_pend_stat.value, d);
3929 DUMP_VAR(fw_pend_stat.hi, d);
3930
3931 DUMP_VAR(txq_stat.value, d);
3932 DUMP_VAR(txq_stat.lo, d);
3933
3934 DUMP_VAR(ieee->scans, d);
3935 DUMP_VAR(reset_backoff, d);
3936
3937 return len;
3938}
3939static DEVICE_ATTR(internals, S_IRUGO, show_internals, NULL);
3940
3941
3942static ssize_t show_bssinfo(struct device *d, struct device_attribute *attr,
3943 char *buf)
3944{
3945 struct ipw2100_priv *priv = dev_get_drvdata(d);
3946 char essid[IW_ESSID_MAX_SIZE + 1];
3947 u8 bssid[ETH_ALEN];
3948 u32 chan = 0;
3949 char * out = buf;
3950 int length;
3951 int ret;
3952
3953 memset(essid, 0, sizeof(essid));
3954 memset(bssid, 0, sizeof(bssid));
3955
3956 length = IW_ESSID_MAX_SIZE;
3957 ret = ipw2100_get_ordinal(priv, IPW_ORD_STAT_ASSN_SSID, essid, &length);
3958 if (ret)
3959 IPW_DEBUG_INFO("failed querying ordinals at line %d\n",
3960 __LINE__);
3961
3962 length = sizeof(bssid);
3963 ret = ipw2100_get_ordinal(priv, IPW_ORD_STAT_ASSN_AP_BSSID,
3964 bssid, &length);
3965 if (ret)
3966 IPW_DEBUG_INFO("failed querying ordinals at line %d\n",
3967 __LINE__);
3968
3969 length = sizeof(u32);
3970 ret = ipw2100_get_ordinal(priv, IPW_ORD_OUR_FREQ, &chan, &length);
3971 if (ret)
3972 IPW_DEBUG_INFO("failed querying ordinals at line %d\n",
3973 __LINE__);
3974
3975 out += sprintf(out, "ESSID: %s\n", essid);
3976 out += sprintf(out, "BSSID: %02x:%02x:%02x:%02x:%02x:%02x\n",
3977 bssid[0], bssid[1], bssid[2],
3978 bssid[3], bssid[4], bssid[5]);
3979 out += sprintf(out, "Channel: %d\n", chan);
3980
3981 return out - buf;
3982}
3983static DEVICE_ATTR(bssinfo, S_IRUGO, show_bssinfo, NULL);
3984
3985
3986#ifdef CONFIG_IPW_DEBUG
3987static ssize_t show_debug_level(struct device_driver *d, char *buf)
3988{
3989 return sprintf(buf, "0x%08X\n", ipw2100_debug_level);
3990}
3991
3992static ssize_t store_debug_level(struct device_driver *d, const char *buf,
3993 size_t count)
3994{
3995 char *p = (char *)buf;
3996 u32 val;
3997
3998 if (p[1] == 'x' || p[1] == 'X' || p[0] == 'x' || p[0] == 'X') {
3999 p++;
4000 if (p[0] == 'x' || p[0] == 'X')
4001 p++;
4002 val = simple_strtoul(p, &p, 16);
4003 } else
4004 val = simple_strtoul(p, &p, 10);
4005 if (p == buf)
4006 IPW_DEBUG_INFO(DRV_NAME
4007 ": %s is not in hex or decimal form.\n", buf);
4008 else
4009 ipw2100_debug_level = val;
4010
4011 return strnlen(buf, count);
4012}
4013static DRIVER_ATTR(debug_level, S_IWUSR | S_IRUGO, show_debug_level,
4014 store_debug_level);
4015#endif /* CONFIG_IPW_DEBUG */
4016
4017
4018static ssize_t show_fatal_error(struct device *d,
4019 struct device_attribute *attr, char *buf)
4020{
4021 struct ipw2100_priv *priv = dev_get_drvdata(d);
4022 char *out = buf;
4023 int i;
4024
4025 if (priv->fatal_error)
4026 out += sprintf(out, "0x%08X\n",
4027 priv->fatal_error);
4028 else
4029 out += sprintf(out, "0\n");
4030
4031 for (i = 1; i <= IPW2100_ERROR_QUEUE; i++) {
4032 if (!priv->fatal_errors[(priv->fatal_index - i) %
4033 IPW2100_ERROR_QUEUE])
4034 continue;
4035
4036 out += sprintf(out, "%d. 0x%08X\n", i,
4037 priv->fatal_errors[(priv->fatal_index - i) %
4038 IPW2100_ERROR_QUEUE]);
4039 }
4040
4041 return out - buf;
4042}
4043
4044static ssize_t store_fatal_error(struct device *d,
4045 struct device_attribute *attr, const char *buf, size_t count)
4046{
4047 struct ipw2100_priv *priv = dev_get_drvdata(d);
4048 schedule_reset(priv);
4049 return count;
4050}
4051static DEVICE_ATTR(fatal_error, S_IWUSR|S_IRUGO, show_fatal_error, store_fatal_error);
4052
4053
4054static ssize_t show_scan_age(struct device *d, struct device_attribute *attr,
4055 char *buf)
4056{
4057 struct ipw2100_priv *priv = dev_get_drvdata(d);
4058 return sprintf(buf, "%d\n", priv->ieee->scan_age);
4059}
4060
4061static ssize_t store_scan_age(struct device *d, struct device_attribute *attr,
4062 const char *buf, size_t count)
4063{
4064 struct ipw2100_priv *priv = dev_get_drvdata(d);
4065 struct net_device *dev = priv->net_dev;
4066 char buffer[] = "00000000";
4067 unsigned long len =
4068 (sizeof(buffer) - 1) > count ? count : sizeof(buffer) - 1;
4069 unsigned long val;
4070 char *p = buffer;
4071
4072 IPW_DEBUG_INFO("enter\n");
4073
4074 strncpy(buffer, buf, len);
4075 buffer[len] = 0;
4076
4077 if (p[1] == 'x' || p[1] == 'X' || p[0] == 'x' || p[0] == 'X') {
4078 p++;
4079 if (p[0] == 'x' || p[0] == 'X')
4080 p++;
4081 val = simple_strtoul(p, &p, 16);
4082 } else
4083 val = simple_strtoul(p, &p, 10);
4084 if (p == buffer) {
4085 IPW_DEBUG_INFO("%s: user supplied invalid value.\n",
4086 dev->name);
4087 } else {
4088 priv->ieee->scan_age = val;
4089 IPW_DEBUG_INFO("set scan_age = %u\n", priv->ieee->scan_age);
4090 }
4091
4092 IPW_DEBUG_INFO("exit\n");
4093 return len;
4094}
4095static DEVICE_ATTR(scan_age, S_IWUSR | S_IRUGO, show_scan_age, store_scan_age);
4096
4097
4098static ssize_t show_rf_kill(struct device *d, struct device_attribute *attr,
4099 char *buf)
4100{
4101 /* 0 - RF kill not enabled
4102 1 - SW based RF kill active (sysfs)
4103 2 - HW based RF kill active
4104 3 - Both HW and SW baed RF kill active */
4105 struct ipw2100_priv *priv = (struct ipw2100_priv *)d->driver_data;
4106 int val = ((priv->status & STATUS_RF_KILL_SW) ? 0x1 : 0x0) |
4107 (rf_kill_active(priv) ? 0x2 : 0x0);
4108 return sprintf(buf, "%i\n", val);
4109}
4110
4111static int ipw_radio_kill_sw(struct ipw2100_priv *priv, int disable_radio)
4112{
4113 if ((disable_radio ? 1 : 0) ==
4114 (priv->status & STATUS_RF_KILL_SW ? 1 : 0))
4115 return 0 ;
4116
4117 IPW_DEBUG_RF_KILL("Manual SW RF Kill set to: RADIO %s\n",
4118 disable_radio ? "OFF" : "ON");
4119
4120 down(&priv->action_sem);
4121
4122 if (disable_radio) {
4123 priv->status |= STATUS_RF_KILL_SW;
4124 ipw2100_down(priv);
4125 } else {
4126 priv->status &= ~STATUS_RF_KILL_SW;
4127 if (rf_kill_active(priv)) {
4128 IPW_DEBUG_RF_KILL("Can not turn radio back on - "
4129 "disabled by HW switch\n");
4130 /* Make sure the RF_KILL check timer is running */
4131 priv->stop_rf_kill = 0;
4132 cancel_delayed_work(&priv->rf_kill);
4133 queue_delayed_work(priv->workqueue, &priv->rf_kill,
4134 HZ);
4135 } else
4136 schedule_reset(priv);
4137 }
4138
4139 up(&priv->action_sem);
4140 return 1;
4141}
4142
4143static ssize_t store_rf_kill(struct device *d, struct device_attribute *attr,
4144 const char *buf, size_t count)
4145{
4146 struct ipw2100_priv *priv = dev_get_drvdata(d);
4147 ipw_radio_kill_sw(priv, buf[0] == '1');
4148 return count;
4149}
4150static DEVICE_ATTR(rf_kill, S_IWUSR|S_IRUGO, show_rf_kill, store_rf_kill);
4151
4152
4153static struct attribute *ipw2100_sysfs_entries[] = {
4154 &dev_attr_hardware.attr,
4155 &dev_attr_registers.attr,
4156 &dev_attr_ordinals.attr,
4157 &dev_attr_pci.attr,
4158 &dev_attr_stats.attr,
4159 &dev_attr_internals.attr,
4160 &dev_attr_bssinfo.attr,
4161 &dev_attr_memory.attr,
4162 &dev_attr_scan_age.attr,
4163 &dev_attr_fatal_error.attr,
4164 &dev_attr_rf_kill.attr,
4165 &dev_attr_cfg.attr,
4166 &dev_attr_status.attr,
4167 &dev_attr_capability.attr,
4168 NULL,
4169};
4170
4171static struct attribute_group ipw2100_attribute_group = {
4172 .attrs = ipw2100_sysfs_entries,
4173};
4174
4175
4176static int status_queue_allocate(struct ipw2100_priv *priv, int entries)
4177{
4178 struct ipw2100_status_queue *q = &priv->status_queue;
4179
4180 IPW_DEBUG_INFO("enter\n");
4181
4182 q->size = entries * sizeof(struct ipw2100_status);
4183 q->drv = (struct ipw2100_status *)pci_alloc_consistent(
4184 priv->pci_dev, q->size, &q->nic);
4185 if (!q->drv) {
4186 IPW_DEBUG_WARNING(
4187 "Can not allocate status queue.\n");
4188 return -ENOMEM;
4189 }
4190
4191 memset(q->drv, 0, q->size);
4192
4193 IPW_DEBUG_INFO("exit\n");
4194
4195 return 0;
4196}
4197
4198static void status_queue_free(struct ipw2100_priv *priv)
4199{
4200 IPW_DEBUG_INFO("enter\n");
4201
4202 if (priv->status_queue.drv) {
4203 pci_free_consistent(
4204 priv->pci_dev, priv->status_queue.size,
4205 priv->status_queue.drv, priv->status_queue.nic);
4206 priv->status_queue.drv = NULL;
4207 }
4208
4209 IPW_DEBUG_INFO("exit\n");
4210}
4211
4212static int bd_queue_allocate(struct ipw2100_priv *priv,
4213 struct ipw2100_bd_queue *q, int entries)
4214{
4215 IPW_DEBUG_INFO("enter\n");
4216
4217 memset(q, 0, sizeof(struct ipw2100_bd_queue));
4218
4219 q->entries = entries;
4220 q->size = entries * sizeof(struct ipw2100_bd);
4221 q->drv = pci_alloc_consistent(priv->pci_dev, q->size, &q->nic);
4222 if (!q->drv) {
4223 IPW_DEBUG_INFO("can't allocate shared memory for buffer descriptors\n");
4224 return -ENOMEM;
4225 }
4226 memset(q->drv, 0, q->size);
4227
4228 IPW_DEBUG_INFO("exit\n");
4229
4230 return 0;
4231}
4232
4233static void bd_queue_free(struct ipw2100_priv *priv,
4234 struct ipw2100_bd_queue *q)
4235{
4236 IPW_DEBUG_INFO("enter\n");
4237
4238 if (!q)
4239 return;
4240
4241 if (q->drv) {
4242 pci_free_consistent(priv->pci_dev,
4243 q->size, q->drv, q->nic);
4244 q->drv = NULL;
4245 }
4246
4247 IPW_DEBUG_INFO("exit\n");
4248}
4249
4250static void bd_queue_initialize(
4251 struct ipw2100_priv *priv, struct ipw2100_bd_queue * q,
4252 u32 base, u32 size, u32 r, u32 w)
4253{
4254 IPW_DEBUG_INFO("enter\n");
4255
4256 IPW_DEBUG_INFO("initializing bd queue at virt=%p, phys=%08x\n", q->drv, (u32)q->nic);
4257
4258 write_register(priv->net_dev, base, q->nic);
4259 write_register(priv->net_dev, size, q->entries);
4260 write_register(priv->net_dev, r, q->oldest);
4261 write_register(priv->net_dev, w, q->next);
4262
4263 IPW_DEBUG_INFO("exit\n");
4264}
4265
4266static void ipw2100_kill_workqueue(struct ipw2100_priv *priv)
4267{
4268 if (priv->workqueue) {
4269 priv->stop_rf_kill = 1;
4270 priv->stop_hang_check = 1;
4271 cancel_delayed_work(&priv->reset_work);
4272 cancel_delayed_work(&priv->security_work);
4273 cancel_delayed_work(&priv->wx_event_work);
4274 cancel_delayed_work(&priv->hang_check);
4275 cancel_delayed_work(&priv->rf_kill);
4276 destroy_workqueue(priv->workqueue);
4277 priv->workqueue = NULL;
4278 }
4279}
4280
4281static int ipw2100_tx_allocate(struct ipw2100_priv *priv)
4282{
4283 int i, j, err = -EINVAL;
4284 void *v;
4285 dma_addr_t p;
4286
4287 IPW_DEBUG_INFO("enter\n");
4288
4289 err = bd_queue_allocate(priv, &priv->tx_queue, TX_QUEUE_LENGTH);
4290 if (err) {
4291 IPW_DEBUG_ERROR("%s: failed bd_queue_allocate\n",
4292 priv->net_dev->name);
4293 return err;
4294 }
4295
4296 priv->tx_buffers = (struct ipw2100_tx_packet *)kmalloc(
4297 TX_PENDED_QUEUE_LENGTH * sizeof(struct ipw2100_tx_packet),
4298 GFP_ATOMIC);
4299 if (!priv->tx_buffers) {
4300 printk(KERN_ERR DRV_NAME ": %s: alloc failed form tx buffers.\n",
4301 priv->net_dev->name);
4302 bd_queue_free(priv, &priv->tx_queue);
4303 return -ENOMEM;
4304 }
4305
4306 for (i = 0; i < TX_PENDED_QUEUE_LENGTH; i++) {
4307 v = pci_alloc_consistent(
4308 priv->pci_dev, sizeof(struct ipw2100_data_header), &p);
4309 if (!v) {
4310 printk(KERN_ERR DRV_NAME ": %s: PCI alloc failed for tx "
4311 "buffers.\n", priv->net_dev->name);
4312 err = -ENOMEM;
4313 break;
4314 }
4315
4316 priv->tx_buffers[i].type = DATA;
4317 priv->tx_buffers[i].info.d_struct.data = (struct ipw2100_data_header*)v;
4318 priv->tx_buffers[i].info.d_struct.data_phys = p;
4319 priv->tx_buffers[i].info.d_struct.txb = NULL;
4320 }
4321
4322 if (i == TX_PENDED_QUEUE_LENGTH)
4323 return 0;
4324
4325 for (j = 0; j < i; j++) {
4326 pci_free_consistent(
4327 priv->pci_dev,
4328 sizeof(struct ipw2100_data_header),
4329 priv->tx_buffers[j].info.d_struct.data,
4330 priv->tx_buffers[j].info.d_struct.data_phys);
4331 }
4332
4333 kfree(priv->tx_buffers);
4334 priv->tx_buffers = NULL;
4335
4336 return err;
4337}
4338
4339static void ipw2100_tx_initialize(struct ipw2100_priv *priv)
4340{
4341 int i;
4342
4343 IPW_DEBUG_INFO("enter\n");
4344
4345 /*
4346 * reinitialize packet info lists
4347 */
4348 INIT_LIST_HEAD(&priv->fw_pend_list);
4349 INIT_STAT(&priv->fw_pend_stat);
4350
4351 /*
4352 * reinitialize lists
4353 */
4354 INIT_LIST_HEAD(&priv->tx_pend_list);
4355 INIT_LIST_HEAD(&priv->tx_free_list);
4356 INIT_STAT(&priv->tx_pend_stat);
4357 INIT_STAT(&priv->tx_free_stat);
4358
4359 for (i = 0; i < TX_PENDED_QUEUE_LENGTH; i++) {
4360 /* We simply drop any SKBs that have been queued for
4361 * transmit */
4362 if (priv->tx_buffers[i].info.d_struct.txb) {
4363 ieee80211_txb_free(priv->tx_buffers[i].info.d_struct.txb);
4364 priv->tx_buffers[i].info.d_struct.txb = NULL;
4365 }
4366
4367 list_add_tail(&priv->tx_buffers[i].list, &priv->tx_free_list);
4368 }
4369
4370 SET_STAT(&priv->tx_free_stat, i);
4371
4372 priv->tx_queue.oldest = 0;
4373 priv->tx_queue.available = priv->tx_queue.entries;
4374 priv->tx_queue.next = 0;
4375 INIT_STAT(&priv->txq_stat);
4376 SET_STAT(&priv->txq_stat, priv->tx_queue.available);
4377
4378 bd_queue_initialize(priv, &priv->tx_queue,
4379 IPW_MEM_HOST_SHARED_TX_QUEUE_BD_BASE,
4380 IPW_MEM_HOST_SHARED_TX_QUEUE_BD_SIZE,
4381 IPW_MEM_HOST_SHARED_TX_QUEUE_READ_INDEX,
4382 IPW_MEM_HOST_SHARED_TX_QUEUE_WRITE_INDEX);
4383
4384 IPW_DEBUG_INFO("exit\n");
4385
4386}
4387
4388static void ipw2100_tx_free(struct ipw2100_priv *priv)
4389{
4390 int i;
4391
4392 IPW_DEBUG_INFO("enter\n");
4393
4394 bd_queue_free(priv, &priv->tx_queue);
4395
4396 if (!priv->tx_buffers)
4397 return;
4398
4399 for (i = 0; i < TX_PENDED_QUEUE_LENGTH; i++) {
4400 if (priv->tx_buffers[i].info.d_struct.txb) {
4401 ieee80211_txb_free(priv->tx_buffers[i].info.d_struct.txb);
4402 priv->tx_buffers[i].info.d_struct.txb = NULL;
4403 }
4404 if (priv->tx_buffers[i].info.d_struct.data)
4405 pci_free_consistent(
4406 priv->pci_dev,
4407 sizeof(struct ipw2100_data_header),
4408 priv->tx_buffers[i].info.d_struct.data,
4409 priv->tx_buffers[i].info.d_struct.data_phys);
4410 }
4411
4412 kfree(priv->tx_buffers);
4413 priv->tx_buffers = NULL;
4414
4415 IPW_DEBUG_INFO("exit\n");
4416}
4417
4418
4419
4420static int ipw2100_rx_allocate(struct ipw2100_priv *priv)
4421{
4422 int i, j, err = -EINVAL;
4423
4424 IPW_DEBUG_INFO("enter\n");
4425
4426 err = bd_queue_allocate(priv, &priv->rx_queue, RX_QUEUE_LENGTH);
4427 if (err) {
4428 IPW_DEBUG_INFO("failed bd_queue_allocate\n");
4429 return err;
4430 }
4431
4432 err = status_queue_allocate(priv, RX_QUEUE_LENGTH);
4433 if (err) {
4434 IPW_DEBUG_INFO("failed status_queue_allocate\n");
4435 bd_queue_free(priv, &priv->rx_queue);
4436 return err;
4437 }
4438
4439 /*
4440 * allocate packets
4441 */
4442 priv->rx_buffers = (struct ipw2100_rx_packet *)
4443 kmalloc(RX_QUEUE_LENGTH * sizeof(struct ipw2100_rx_packet),
4444 GFP_KERNEL);
4445 if (!priv->rx_buffers) {
4446 IPW_DEBUG_INFO("can't allocate rx packet buffer table\n");
4447
4448 bd_queue_free(priv, &priv->rx_queue);
4449
4450 status_queue_free(priv);
4451
4452 return -ENOMEM;
4453 }
4454
4455 for (i = 0; i < RX_QUEUE_LENGTH; i++) {
4456 struct ipw2100_rx_packet *packet = &priv->rx_buffers[i];
4457
4458 err = ipw2100_alloc_skb(priv, packet);
4459 if (unlikely(err)) {
4460 err = -ENOMEM;
4461 break;
4462 }
4463
4464 /* The BD holds the cache aligned address */
4465 priv->rx_queue.drv[i].host_addr = packet->dma_addr;
4466 priv->rx_queue.drv[i].buf_length = IPW_RX_NIC_BUFFER_LENGTH;
4467 priv->status_queue.drv[i].status_fields = 0;
4468 }
4469
4470 if (i == RX_QUEUE_LENGTH)
4471 return 0;
4472
4473 for (j = 0; j < i; j++) {
4474 pci_unmap_single(priv->pci_dev, priv->rx_buffers[j].dma_addr,
4475 sizeof(struct ipw2100_rx_packet),
4476 PCI_DMA_FROMDEVICE);
4477 dev_kfree_skb(priv->rx_buffers[j].skb);
4478 }
4479
4480 kfree(priv->rx_buffers);
4481 priv->rx_buffers = NULL;
4482
4483 bd_queue_free(priv, &priv->rx_queue);
4484
4485 status_queue_free(priv);
4486
4487 return err;
4488}
4489
4490static void ipw2100_rx_initialize(struct ipw2100_priv *priv)
4491{
4492 IPW_DEBUG_INFO("enter\n");
4493
4494 priv->rx_queue.oldest = 0;
4495 priv->rx_queue.available = priv->rx_queue.entries - 1;
4496 priv->rx_queue.next = priv->rx_queue.entries - 1;
4497
4498 INIT_STAT(&priv->rxq_stat);
4499 SET_STAT(&priv->rxq_stat, priv->rx_queue.available);
4500
4501 bd_queue_initialize(priv, &priv->rx_queue,
4502 IPW_MEM_HOST_SHARED_RX_BD_BASE,
4503 IPW_MEM_HOST_SHARED_RX_BD_SIZE,
4504 IPW_MEM_HOST_SHARED_RX_READ_INDEX,
4505 IPW_MEM_HOST_SHARED_RX_WRITE_INDEX);
4506
4507 /* set up the status queue */
4508 write_register(priv->net_dev, IPW_MEM_HOST_SHARED_RX_STATUS_BASE,
4509 priv->status_queue.nic);
4510
4511 IPW_DEBUG_INFO("exit\n");
4512}
4513
4514static void ipw2100_rx_free(struct ipw2100_priv *priv)
4515{
4516 int i;
4517
4518 IPW_DEBUG_INFO("enter\n");
4519
4520 bd_queue_free(priv, &priv->rx_queue);
4521 status_queue_free(priv);
4522
4523 if (!priv->rx_buffers)
4524 return;
4525
4526 for (i = 0; i < RX_QUEUE_LENGTH; i++) {
4527 if (priv->rx_buffers[i].rxp) {
4528 pci_unmap_single(priv->pci_dev,
4529 priv->rx_buffers[i].dma_addr,
4530 sizeof(struct ipw2100_rx),
4531 PCI_DMA_FROMDEVICE);
4532 dev_kfree_skb(priv->rx_buffers[i].skb);
4533 }
4534 }
4535
4536 kfree(priv->rx_buffers);
4537 priv->rx_buffers = NULL;
4538
4539 IPW_DEBUG_INFO("exit\n");
4540}
4541
4542static int ipw2100_read_mac_address(struct ipw2100_priv *priv)
4543{
4544 u32 length = ETH_ALEN;
4545 u8 mac[ETH_ALEN];
4546
4547 int err;
4548
4549 err = ipw2100_get_ordinal(priv, IPW_ORD_STAT_ADAPTER_MAC,
4550 mac, &length);
4551 if (err) {
4552 IPW_DEBUG_INFO("MAC address read failed\n");
4553 return -EIO;
4554 }
4555 IPW_DEBUG_INFO("card MAC is %02X:%02X:%02X:%02X:%02X:%02X\n",
4556 mac[0], mac[1], mac[2], mac[3], mac[4], mac[5]);
4557
4558 memcpy(priv->net_dev->dev_addr, mac, ETH_ALEN);
4559
4560 return 0;
4561}
4562
4563/********************************************************************
4564 *
4565 * Firmware Commands
4566 *
4567 ********************************************************************/
4568
4569static int ipw2100_set_mac_address(struct ipw2100_priv *priv, int batch_mode)
4570{
4571 struct host_command cmd = {
4572 .host_command = ADAPTER_ADDRESS,
4573 .host_command_sequence = 0,
4574 .host_command_length = ETH_ALEN
4575 };
4576 int err;
4577
4578 IPW_DEBUG_HC("SET_MAC_ADDRESS\n");
4579
4580 IPW_DEBUG_INFO("enter\n");
4581
4582 if (priv->config & CFG_CUSTOM_MAC) {
4583 memcpy(cmd.host_command_parameters, priv->mac_addr,
4584 ETH_ALEN);
4585 memcpy(priv->net_dev->dev_addr, priv->mac_addr, ETH_ALEN);
4586 } else
4587 memcpy(cmd.host_command_parameters, priv->net_dev->dev_addr,
4588 ETH_ALEN);
4589
4590 err = ipw2100_hw_send_command(priv, &cmd);
4591
4592 IPW_DEBUG_INFO("exit\n");
4593 return err;
4594}
4595
4596static int ipw2100_set_port_type(struct ipw2100_priv *priv, u32 port_type,
4597 int batch_mode)
4598{
4599 struct host_command cmd = {
4600 .host_command = PORT_TYPE,
4601 .host_command_sequence = 0,
4602 .host_command_length = sizeof(u32)
4603 };
4604 int err;
4605
4606 switch (port_type) {
4607 case IW_MODE_INFRA:
4608 cmd.host_command_parameters[0] = IPW_BSS;
4609 break;
4610 case IW_MODE_ADHOC:
4611 cmd.host_command_parameters[0] = IPW_IBSS;
4612 break;
4613 }
4614
4615 IPW_DEBUG_HC("PORT_TYPE: %s\n",
4616 port_type == IPW_IBSS ? "Ad-Hoc" : "Managed");
4617
4618 if (!batch_mode) {
4619 err = ipw2100_disable_adapter(priv);
4620 if (err) {
4621 printk(KERN_ERR DRV_NAME ": %s: Could not disable adapter %d\n",
4622 priv->net_dev->name, err);
4623 return err;
4624 }
4625 }
4626
4627 /* send cmd to firmware */
4628 err = ipw2100_hw_send_command(priv, &cmd);
4629
4630 if (!batch_mode)
4631 ipw2100_enable_adapter(priv);
4632
4633 return err;
4634}
4635
4636
4637static int ipw2100_set_channel(struct ipw2100_priv *priv, u32 channel,
4638 int batch_mode)
4639{
4640 struct host_command cmd = {
4641 .host_command = CHANNEL,
4642 .host_command_sequence = 0,
4643 .host_command_length = sizeof(u32)
4644 };
4645 int err;
4646
4647 cmd.host_command_parameters[0] = channel;
4648
4649 IPW_DEBUG_HC("CHANNEL: %d\n", channel);
4650
4651 /* If BSS then we don't support channel selection */
4652 if (priv->ieee->iw_mode == IW_MODE_INFRA)
4653 return 0;
4654
4655 if ((channel != 0) &&
4656 ((channel < REG_MIN_CHANNEL) || (channel > REG_MAX_CHANNEL)))
4657 return -EINVAL;
4658
4659 if (!batch_mode) {
4660 err = ipw2100_disable_adapter(priv);
4661 if (err)
4662 return err;
4663 }
4664
4665 err = ipw2100_hw_send_command(priv, &cmd);
4666 if (err) {
4667 IPW_DEBUG_INFO("Failed to set channel to %d",
4668 channel);
4669 return err;
4670 }
4671
4672 if (channel)
4673 priv->config |= CFG_STATIC_CHANNEL;
4674 else
4675 priv->config &= ~CFG_STATIC_CHANNEL;
4676
4677 priv->channel = channel;
4678
4679 if (!batch_mode) {
4680 err = ipw2100_enable_adapter(priv);
4681 if (err)
4682 return err;
4683 }
4684
4685 return 0;
4686}
4687
4688static int ipw2100_system_config(struct ipw2100_priv *priv, int batch_mode)
4689{
4690 struct host_command cmd = {
4691 .host_command = SYSTEM_CONFIG,
4692 .host_command_sequence = 0,
4693 .host_command_length = 12,
4694 };
4695 u32 ibss_mask, len = sizeof(u32);
4696 int err;
4697
4698 /* Set system configuration */
4699
4700 if (!batch_mode) {
4701 err = ipw2100_disable_adapter(priv);
4702 if (err)
4703 return err;
4704 }
4705
4706 if (priv->ieee->iw_mode == IW_MODE_ADHOC)
4707 cmd.host_command_parameters[0] |= IPW_CFG_IBSS_AUTO_START;
4708
4709 cmd.host_command_parameters[0] |= IPW_CFG_IBSS_MASK |
4710 IPW_CFG_BSS_MASK |
4711 IPW_CFG_802_1x_ENABLE;
4712
4713 if (!(priv->config & CFG_LONG_PREAMBLE))
4714 cmd.host_command_parameters[0] |= IPW_CFG_PREAMBLE_AUTO;
4715
4716 err = ipw2100_get_ordinal(priv,
4717 IPW_ORD_EEPROM_IBSS_11B_CHANNELS,
4718 &ibss_mask, &len);
4719 if (err)
4720 ibss_mask = IPW_IBSS_11B_DEFAULT_MASK;
4721
4722 cmd.host_command_parameters[1] = REG_CHANNEL_MASK;
4723 cmd.host_command_parameters[2] = REG_CHANNEL_MASK & ibss_mask;
4724
4725 /* 11b only */
4726 /*cmd.host_command_parameters[0] |= DIVERSITY_ANTENNA_A;*/
4727
4728 err = ipw2100_hw_send_command(priv, &cmd);
4729 if (err)
4730 return err;
4731
4732/* If IPv6 is configured in the kernel then we don't want to filter out all
4733 * of the multicast packets as IPv6 needs some. */
4734#if !defined(CONFIG_IPV6) && !defined(CONFIG_IPV6_MODULE)
4735 cmd.host_command = ADD_MULTICAST;
4736 cmd.host_command_sequence = 0;
4737 cmd.host_command_length = 0;
4738
4739 ipw2100_hw_send_command(priv, &cmd);
4740#endif
4741 if (!batch_mode) {
4742 err = ipw2100_enable_adapter(priv);
4743 if (err)
4744 return err;
4745 }
4746
4747 return 0;
4748}
4749
4750static int ipw2100_set_tx_rates(struct ipw2100_priv *priv, u32 rate,
4751 int batch_mode)
4752{
4753 struct host_command cmd = {
4754 .host_command = BASIC_TX_RATES,
4755 .host_command_sequence = 0,
4756 .host_command_length = 4
4757 };
4758 int err;
4759
4760 cmd.host_command_parameters[0] = rate & TX_RATE_MASK;
4761
4762 if (!batch_mode) {
4763 err = ipw2100_disable_adapter(priv);
4764 if (err)
4765 return err;
4766 }
4767
4768 /* Set BASIC TX Rate first */
4769 ipw2100_hw_send_command(priv, &cmd);
4770
4771 /* Set TX Rate */
4772 cmd.host_command = TX_RATES;
4773 ipw2100_hw_send_command(priv, &cmd);
4774
4775 /* Set MSDU TX Rate */
4776 cmd.host_command = MSDU_TX_RATES;
4777 ipw2100_hw_send_command(priv, &cmd);
4778
4779 if (!batch_mode) {
4780 err = ipw2100_enable_adapter(priv);
4781 if (err)
4782 return err;
4783 }
4784
4785 priv->tx_rates = rate;
4786
4787 return 0;
4788}
4789
4790static int ipw2100_set_power_mode(struct ipw2100_priv *priv,
4791 int power_level)
4792{
4793 struct host_command cmd = {
4794 .host_command = POWER_MODE,
4795 .host_command_sequence = 0,
4796 .host_command_length = 4
4797 };
4798 int err;
4799
4800 cmd.host_command_parameters[0] = power_level;
4801
4802 err = ipw2100_hw_send_command(priv, &cmd);
4803 if (err)
4804 return err;
4805
4806 if (power_level == IPW_POWER_MODE_CAM)
4807 priv->power_mode = IPW_POWER_LEVEL(priv->power_mode);
4808 else
4809 priv->power_mode = IPW_POWER_ENABLED | power_level;
4810
4811#ifdef CONFIG_IPW2100_TX_POWER
4812 if (priv->port_type == IBSS &&
4813 priv->adhoc_power != DFTL_IBSS_TX_POWER) {
4814 /* Set beacon interval */
4815 cmd.host_command = TX_POWER_INDEX;
4816 cmd.host_command_parameters[0] = (u32)priv->adhoc_power;
4817
4818 err = ipw2100_hw_send_command(priv, &cmd);
4819 if (err)
4820 return err;
4821 }
4822#endif
4823
4824 return 0;
4825}
4826
4827
4828static int ipw2100_set_rts_threshold(struct ipw2100_priv *priv, u32 threshold)
4829{
4830 struct host_command cmd = {
4831 .host_command = RTS_THRESHOLD,
4832 .host_command_sequence = 0,
4833 .host_command_length = 4
4834 };
4835 int err;
4836
4837 if (threshold & RTS_DISABLED)
4838 cmd.host_command_parameters[0] = MAX_RTS_THRESHOLD;
4839 else
4840 cmd.host_command_parameters[0] = threshold & ~RTS_DISABLED;
4841
4842 err = ipw2100_hw_send_command(priv, &cmd);
4843 if (err)
4844 return err;
4845
4846 priv->rts_threshold = threshold;
4847
4848 return 0;
4849}
4850
4851#if 0
4852int ipw2100_set_fragmentation_threshold(struct ipw2100_priv *priv,
4853 u32 threshold, int batch_mode)
4854{
4855 struct host_command cmd = {
4856 .host_command = FRAG_THRESHOLD,
4857 .host_command_sequence = 0,
4858 .host_command_length = 4,
4859 .host_command_parameters[0] = 0,
4860 };
4861 int err;
4862
4863 if (!batch_mode) {
4864 err = ipw2100_disable_adapter(priv);
4865 if (err)
4866 return err;
4867 }
4868
4869 if (threshold == 0)
4870 threshold = DEFAULT_FRAG_THRESHOLD;
4871 else {
4872 threshold = max(threshold, MIN_FRAG_THRESHOLD);
4873 threshold = min(threshold, MAX_FRAG_THRESHOLD);
4874 }
4875
4876 cmd.host_command_parameters[0] = threshold;
4877
4878 IPW_DEBUG_HC("FRAG_THRESHOLD: %u\n", threshold);
4879
4880 err = ipw2100_hw_send_command(priv, &cmd);
4881
4882 if (!batch_mode)
4883 ipw2100_enable_adapter(priv);
4884
4885 if (!err)
4886 priv->frag_threshold = threshold;
4887
4888 return err;
4889}
4890#endif
4891
4892static int ipw2100_set_short_retry(struct ipw2100_priv *priv, u32 retry)
4893{
4894 struct host_command cmd = {
4895 .host_command = SHORT_RETRY_LIMIT,
4896 .host_command_sequence = 0,
4897 .host_command_length = 4
4898 };
4899 int err;
4900
4901 cmd.host_command_parameters[0] = retry;
4902
4903 err = ipw2100_hw_send_command(priv, &cmd);
4904 if (err)
4905 return err;
4906
4907 priv->short_retry_limit = retry;
4908
4909 return 0;
4910}
4911
4912static int ipw2100_set_long_retry(struct ipw2100_priv *priv, u32 retry)
4913{
4914 struct host_command cmd = {
4915 .host_command = LONG_RETRY_LIMIT,
4916 .host_command_sequence = 0,
4917 .host_command_length = 4
4918 };
4919 int err;
4920
4921 cmd.host_command_parameters[0] = retry;
4922
4923 err = ipw2100_hw_send_command(priv, &cmd);
4924 if (err)
4925 return err;
4926
4927 priv->long_retry_limit = retry;
4928
4929 return 0;
4930}
4931
4932
4933static int ipw2100_set_mandatory_bssid(struct ipw2100_priv *priv, u8 *bssid,
4934 int batch_mode)
4935{
4936 struct host_command cmd = {
4937 .host_command = MANDATORY_BSSID,
4938 .host_command_sequence = 0,
4939 .host_command_length = (bssid == NULL) ? 0 : ETH_ALEN
4940 };
4941 int err;
4942
4943#ifdef CONFIG_IPW_DEBUG
4944 if (bssid != NULL)
4945 IPW_DEBUG_HC(
4946 "MANDATORY_BSSID: %02X:%02X:%02X:%02X:%02X:%02X\n",
4947 bssid[0], bssid[1], bssid[2], bssid[3], bssid[4],
4948 bssid[5]);
4949 else
4950 IPW_DEBUG_HC("MANDATORY_BSSID: <clear>\n");
4951#endif
4952 /* if BSSID is empty then we disable mandatory bssid mode */
4953 if (bssid != NULL)
4954 memcpy((u8 *)cmd.host_command_parameters, bssid, ETH_ALEN);
4955
4956 if (!batch_mode) {
4957 err = ipw2100_disable_adapter(priv);
4958 if (err)
4959 return err;
4960 }
4961
4962 err = ipw2100_hw_send_command(priv, &cmd);
4963
4964 if (!batch_mode)
4965 ipw2100_enable_adapter(priv);
4966
4967 return err;
4968}
4969
4970#ifdef CONFIG_IEEE80211_WPA
4971static int ipw2100_disassociate_bssid(struct ipw2100_priv *priv)
4972{
4973 struct host_command cmd = {
4974 .host_command = DISASSOCIATION_BSSID,
4975 .host_command_sequence = 0,
4976 .host_command_length = ETH_ALEN
4977 };
4978 int err;
4979 int len;
4980
4981 IPW_DEBUG_HC("DISASSOCIATION_BSSID\n");
4982
4983 len = ETH_ALEN;
4984 /* The Firmware currently ignores the BSSID and just disassociates from
4985 * the currently associated AP -- but in the off chance that a future
4986 * firmware does use the BSSID provided here, we go ahead and try and
4987 * set it to the currently associated AP's BSSID */
4988 memcpy(cmd.host_command_parameters, priv->bssid, ETH_ALEN);
4989
4990 err = ipw2100_hw_send_command(priv, &cmd);
4991
4992 return err;
4993}
4994#endif
4995
4996/*
4997 * Pseudo code for setting up wpa_frame:
4998 */
4999#if 0
5000void x(struct ieee80211_assoc_frame *wpa_assoc)
5001{
5002 struct ipw2100_wpa_assoc_frame frame;
5003 frame->fixed_ie_mask = IPW_WPA_CAPABILTIES |
5004 IPW_WPA_LISTENINTERVAL |
5005 IPW_WPA_AP_ADDRESS;
5006 frame->capab_info = wpa_assoc->capab_info;
5007 frame->lisen_interval = wpa_assoc->listent_interval;
5008 memcpy(frame->current_ap, wpa_assoc->current_ap, ETH_ALEN);
5009
5010 /* UNKNOWN -- I'm not postivive about this part; don't have any WPA
5011 * setup here to test it with.
5012 *
5013 * Walk the IEs in the wpa_assoc and figure out the total size of all
5014 * that data. Stick that into frame->var_ie_len. Then memcpy() all of
5015 * the IEs from wpa_frame into frame.
5016 */
5017 frame->var_ie_len = calculate_ie_len(wpa_assoc);
5018 memcpy(frame->var_ie, wpa_assoc->variable, frame->var_ie_len);
5019
5020 ipw2100_set_wpa_ie(priv, &frame, 0);
5021}
5022#endif
5023
5024
5025
5026
5027static int ipw2100_set_wpa_ie(struct ipw2100_priv *,
5028 struct ipw2100_wpa_assoc_frame *, int)
5029__attribute__ ((unused));
5030
5031static int ipw2100_set_wpa_ie(struct ipw2100_priv *priv,
5032 struct ipw2100_wpa_assoc_frame *wpa_frame,
5033 int batch_mode)
5034{
5035 struct host_command cmd = {
5036 .host_command = SET_WPA_IE,
5037 .host_command_sequence = 0,
5038 .host_command_length = sizeof(struct ipw2100_wpa_assoc_frame),
5039 };
5040 int err;
5041
5042 IPW_DEBUG_HC("SET_WPA_IE\n");
5043
5044 if (!batch_mode) {
5045 err = ipw2100_disable_adapter(priv);
5046 if (err)
5047 return err;
5048 }
5049
5050 memcpy(cmd.host_command_parameters, wpa_frame,
5051 sizeof(struct ipw2100_wpa_assoc_frame));
5052
5053 err = ipw2100_hw_send_command(priv, &cmd);
5054
5055 if (!batch_mode) {
5056 if (ipw2100_enable_adapter(priv))
5057 err = -EIO;
5058 }
5059
5060 return err;
5061}
5062
5063struct security_info_params {
5064 u32 allowed_ciphers;
5065 u16 version;
5066 u8 auth_mode;
5067 u8 replay_counters_number;
5068 u8 unicast_using_group;
5069} __attribute__ ((packed));
5070
5071static int ipw2100_set_security_information(struct ipw2100_priv *priv,
5072 int auth_mode,
5073 int security_level,
5074 int unicast_using_group,
5075 int batch_mode)
5076{
5077 struct host_command cmd = {
5078 .host_command = SET_SECURITY_INFORMATION,
5079 .host_command_sequence = 0,
5080 .host_command_length = sizeof(struct security_info_params)
5081 };
5082 struct security_info_params *security =
5083 (struct security_info_params *)&cmd.host_command_parameters;
5084 int err;
5085 memset(security, 0, sizeof(*security));
5086
5087 /* If shared key AP authentication is turned on, then we need to
5088 * configure the firmware to try and use it.
5089 *
5090 * Actual data encryption/decryption is handled by the host. */
5091 security->auth_mode = auth_mode;
5092 security->unicast_using_group = unicast_using_group;
5093
5094 switch (security_level) {
5095 default:
5096 case SEC_LEVEL_0:
5097 security->allowed_ciphers = IPW_NONE_CIPHER;
5098 break;
5099 case SEC_LEVEL_1:
5100 security->allowed_ciphers = IPW_WEP40_CIPHER |
5101 IPW_WEP104_CIPHER;
5102 break;
5103 case SEC_LEVEL_2:
5104 security->allowed_ciphers = IPW_WEP40_CIPHER |
5105 IPW_WEP104_CIPHER | IPW_TKIP_CIPHER;
5106 break;
5107 case SEC_LEVEL_2_CKIP:
5108 security->allowed_ciphers = IPW_WEP40_CIPHER |
5109 IPW_WEP104_CIPHER | IPW_CKIP_CIPHER;
5110 break;
5111 case SEC_LEVEL_3:
5112 security->allowed_ciphers = IPW_WEP40_CIPHER |
5113 IPW_WEP104_CIPHER | IPW_TKIP_CIPHER | IPW_CCMP_CIPHER;
5114 break;
5115 }
5116
5117 IPW_DEBUG_HC(
5118 "SET_SECURITY_INFORMATION: auth:%d cipher:0x%02X (level %d)\n",
5119 security->auth_mode, security->allowed_ciphers, security_level);
5120
5121 security->replay_counters_number = 0;
5122
5123 if (!batch_mode) {
5124 err = ipw2100_disable_adapter(priv);
5125 if (err)
5126 return err;
5127 }
5128
5129 err = ipw2100_hw_send_command(priv, &cmd);
5130
5131 if (!batch_mode)
5132 ipw2100_enable_adapter(priv);
5133
5134 return err;
5135}
5136
5137static int ipw2100_set_tx_power(struct ipw2100_priv *priv,
5138 u32 tx_power)
5139{
5140 struct host_command cmd = {
5141 .host_command = TX_POWER_INDEX,
5142 .host_command_sequence = 0,
5143 .host_command_length = 4
5144 };
5145 int err = 0;
5146
5147 cmd.host_command_parameters[0] = tx_power;
5148
5149 if (priv->ieee->iw_mode == IW_MODE_ADHOC)
5150 err = ipw2100_hw_send_command(priv, &cmd);
5151 if (!err)
5152 priv->tx_power = tx_power;
5153
5154 return 0;
5155}
5156
5157static int ipw2100_set_ibss_beacon_interval(struct ipw2100_priv *priv,
5158 u32 interval, int batch_mode)
5159{
5160 struct host_command cmd = {
5161 .host_command = BEACON_INTERVAL,
5162 .host_command_sequence = 0,
5163 .host_command_length = 4
5164 };
5165 int err;
5166
5167 cmd.host_command_parameters[0] = interval;
5168
5169 IPW_DEBUG_INFO("enter\n");
5170
5171 if (priv->ieee->iw_mode == IW_MODE_ADHOC) {
5172 if (!batch_mode) {
5173 err = ipw2100_disable_adapter(priv);
5174 if (err)
5175 return err;
5176 }
5177
5178 ipw2100_hw_send_command(priv, &cmd);
5179
5180 if (!batch_mode) {
5181 err = ipw2100_enable_adapter(priv);
5182 if (err)
5183 return err;
5184 }
5185 }
5186
5187 IPW_DEBUG_INFO("exit\n");
5188
5189 return 0;
5190}
5191
5192
5193void ipw2100_queues_initialize(struct ipw2100_priv *priv)
5194{
5195 ipw2100_tx_initialize(priv);
5196 ipw2100_rx_initialize(priv);
5197 ipw2100_msg_initialize(priv);
5198}
5199
5200void ipw2100_queues_free(struct ipw2100_priv *priv)
5201{
5202 ipw2100_tx_free(priv);
5203 ipw2100_rx_free(priv);
5204 ipw2100_msg_free(priv);
5205}
5206
5207int ipw2100_queues_allocate(struct ipw2100_priv *priv)
5208{
5209 if (ipw2100_tx_allocate(priv) ||
5210 ipw2100_rx_allocate(priv) ||
5211 ipw2100_msg_allocate(priv))
5212 goto fail;
5213
5214 return 0;
5215
5216 fail:
5217 ipw2100_tx_free(priv);
5218 ipw2100_rx_free(priv);
5219 ipw2100_msg_free(priv);
5220 return -ENOMEM;
5221}
5222
5223#define IPW_PRIVACY_CAPABLE 0x0008
5224
5225static int ipw2100_set_wep_flags(struct ipw2100_priv *priv, u32 flags,
5226 int batch_mode)
5227{
5228 struct host_command cmd = {
5229 .host_command = WEP_FLAGS,
5230 .host_command_sequence = 0,
5231 .host_command_length = 4
5232 };
5233 int err;
5234
5235 cmd.host_command_parameters[0] = flags;
5236
5237 IPW_DEBUG_HC("WEP_FLAGS: flags = 0x%08X\n", flags);
5238
5239 if (!batch_mode) {
5240 err = ipw2100_disable_adapter(priv);
5241 if (err) {
5242 printk(KERN_ERR DRV_NAME ": %s: Could not disable adapter %d\n",
5243 priv->net_dev->name, err);
5244 return err;
5245 }
5246 }
5247
5248 /* send cmd to firmware */
5249 err = ipw2100_hw_send_command(priv, &cmd);
5250
5251 if (!batch_mode)
5252 ipw2100_enable_adapter(priv);
5253
5254 return err;
5255}
5256
5257struct ipw2100_wep_key {
5258 u8 idx;
5259 u8 len;
5260 u8 key[13];
5261};
5262
5263/* Macros to ease up priting WEP keys */
5264#define WEP_FMT_64 "%02X%02X%02X%02X-%02X"
5265#define WEP_FMT_128 "%02X%02X%02X%02X-%02X%02X%02X%02X-%02X%02X%02X"
5266#define WEP_STR_64(x) x[0],x[1],x[2],x[3],x[4]
5267#define WEP_STR_128(x) x[0],x[1],x[2],x[3],x[4],x[5],x[6],x[7],x[8],x[9],x[10]
5268
5269
5270/**
5271 * Set a the wep key
5272 *
5273 * @priv: struct to work on
5274 * @idx: index of the key we want to set
5275 * @key: ptr to the key data to set
5276 * @len: length of the buffer at @key
5277 * @batch_mode: FIXME perform the operation in batch mode, not
5278 * disabling the device.
5279 *
5280 * @returns 0 if OK, < 0 errno code on error.
5281 *
5282 * Fill out a command structure with the new wep key, length an
5283 * index and send it down the wire.
5284 */
5285static int ipw2100_set_key(struct ipw2100_priv *priv,
5286 int idx, char *key, int len, int batch_mode)
5287{
5288 int keylen = len ? (len <= 5 ? 5 : 13) : 0;
5289 struct host_command cmd = {
5290 .host_command = WEP_KEY_INFO,
5291 .host_command_sequence = 0,
5292 .host_command_length = sizeof(struct ipw2100_wep_key),
5293 };
5294 struct ipw2100_wep_key *wep_key = (void*)cmd.host_command_parameters;
5295 int err;
5296
5297 IPW_DEBUG_HC("WEP_KEY_INFO: index = %d, len = %d/%d\n",
5298 idx, keylen, len);
5299
5300 /* NOTE: We don't check cached values in case the firmware was reset
5301 * or some other problem is occuring. If the user is setting the key,
5302 * then we push the change */
5303
5304 wep_key->idx = idx;
5305 wep_key->len = keylen;
5306
5307 if (keylen) {
5308 memcpy(wep_key->key, key, len);
5309 memset(wep_key->key + len, 0, keylen - len);
5310 }
5311
5312 /* Will be optimized out on debug not being configured in */
5313 if (keylen == 0)
5314 IPW_DEBUG_WEP("%s: Clearing key %d\n",
5315 priv->net_dev->name, wep_key->idx);
5316 else if (keylen == 5)
5317 IPW_DEBUG_WEP("%s: idx: %d, len: %d key: " WEP_FMT_64 "\n",
5318 priv->net_dev->name, wep_key->idx, wep_key->len,
5319 WEP_STR_64(wep_key->key));
5320 else
5321 IPW_DEBUG_WEP("%s: idx: %d, len: %d key: " WEP_FMT_128
5322 "\n",
5323 priv->net_dev->name, wep_key->idx, wep_key->len,
5324 WEP_STR_128(wep_key->key));
5325
5326 if (!batch_mode) {
5327 err = ipw2100_disable_adapter(priv);
5328 /* FIXME: IPG: shouldn't this prink be in _disable_adapter()? */
5329 if (err) {
5330 printk(KERN_ERR DRV_NAME ": %s: Could not disable adapter %d\n",
5331 priv->net_dev->name, err);
5332 return err;
5333 }
5334 }
5335
5336 /* send cmd to firmware */
5337 err = ipw2100_hw_send_command(priv, &cmd);
5338
5339 if (!batch_mode) {
5340 int err2 = ipw2100_enable_adapter(priv);
5341 if (err == 0)
5342 err = err2;
5343 }
5344 return err;
5345}
5346
5347static int ipw2100_set_key_index(struct ipw2100_priv *priv,
5348 int idx, int batch_mode)
5349{
5350 struct host_command cmd = {
5351 .host_command = WEP_KEY_INDEX,
5352 .host_command_sequence = 0,
5353 .host_command_length = 4,
5354 .host_command_parameters = { idx },
5355 };
5356 int err;
5357
5358 IPW_DEBUG_HC("WEP_KEY_INDEX: index = %d\n", idx);
5359
5360 if (idx < 0 || idx > 3)
5361 return -EINVAL;
5362
5363 if (!batch_mode) {
5364 err = ipw2100_disable_adapter(priv);
5365 if (err) {
5366 printk(KERN_ERR DRV_NAME ": %s: Could not disable adapter %d\n",
5367 priv->net_dev->name, err);
5368 return err;
5369 }
5370 }
5371
5372 /* send cmd to firmware */
5373 err = ipw2100_hw_send_command(priv, &cmd);
5374
5375 if (!batch_mode)
5376 ipw2100_enable_adapter(priv);
5377
5378 return err;
5379}
5380
5381
5382static int ipw2100_configure_security(struct ipw2100_priv *priv,
5383 int batch_mode)
5384{
5385 int i, err, auth_mode, sec_level, use_group;
5386
5387 if (!(priv->status & STATUS_RUNNING))
5388 return 0;
5389
5390 if (!batch_mode) {
5391 err = ipw2100_disable_adapter(priv);
5392 if (err)
5393 return err;
5394 }
5395
5396 if (!priv->sec.enabled) {
5397 err = ipw2100_set_security_information(
5398 priv, IPW_AUTH_OPEN, SEC_LEVEL_0, 0, 1);
5399 } else {
5400 auth_mode = IPW_AUTH_OPEN;
5401 if ((priv->sec.flags & SEC_AUTH_MODE) &&
5402 (priv->sec.auth_mode == WLAN_AUTH_SHARED_KEY))
5403 auth_mode = IPW_AUTH_SHARED;
5404
5405 sec_level = SEC_LEVEL_0;
5406 if (priv->sec.flags & SEC_LEVEL)
5407 sec_level = priv->sec.level;
5408
5409 use_group = 0;
5410 if (priv->sec.flags & SEC_UNICAST_GROUP)
5411 use_group = priv->sec.unicast_uses_group;
5412
5413 err = ipw2100_set_security_information(
5414 priv, auth_mode, sec_level, use_group, 1);
5415 }
5416
5417 if (err)
5418 goto exit;
5419
5420 if (priv->sec.enabled) {
5421 for (i = 0; i < 4; i++) {
5422 if (!(priv->sec.flags & (1 << i))) {
5423 memset(priv->sec.keys[i], 0, WEP_KEY_LEN);
5424 priv->sec.key_sizes[i] = 0;
5425 } else {
5426 err = ipw2100_set_key(priv, i,
5427 priv->sec.keys[i],
5428 priv->sec.key_sizes[i],
5429 1);
5430 if (err)
5431 goto exit;
5432 }
5433 }
5434
5435 ipw2100_set_key_index(priv, priv->ieee->tx_keyidx, 1);
5436 }
5437
5438 /* Always enable privacy so the Host can filter WEP packets if
5439 * encrypted data is sent up */
5440 err = ipw2100_set_wep_flags(
5441 priv, priv->sec.enabled ? IPW_PRIVACY_CAPABLE : 0, 1);
5442 if (err)
5443 goto exit;
5444
5445 priv->status &= ~STATUS_SECURITY_UPDATED;
5446
5447 exit:
5448 if (!batch_mode)
5449 ipw2100_enable_adapter(priv);
5450
5451 return err;
5452}
5453
5454static void ipw2100_security_work(struct ipw2100_priv *priv)
5455{
5456 /* If we happen to have reconnected before we get a chance to
5457 * process this, then update the security settings--which causes
5458 * a disassociation to occur */
5459 if (!(priv->status & STATUS_ASSOCIATED) &&
5460 priv->status & STATUS_SECURITY_UPDATED)
5461 ipw2100_configure_security(priv, 0);
5462}
5463
5464static void shim__set_security(struct net_device *dev,
5465 struct ieee80211_security *sec)
5466{
5467 struct ipw2100_priv *priv = ieee80211_priv(dev);
5468 int i, force_update = 0;
5469
5470 down(&priv->action_sem);
5471 if (!(priv->status & STATUS_INITIALIZED))
5472 goto done;
5473
5474 for (i = 0; i < 4; i++) {
5475 if (sec->flags & (1 << i)) {
5476 priv->sec.key_sizes[i] = sec->key_sizes[i];
5477 if (sec->key_sizes[i] == 0)
5478 priv->sec.flags &= ~(1 << i);
5479 else
5480 memcpy(priv->sec.keys[i], sec->keys[i],
5481 sec->key_sizes[i]);
5482 priv->sec.flags |= (1 << i);
5483 priv->status |= STATUS_SECURITY_UPDATED;
5484 }
5485 }
5486
5487 if ((sec->flags & SEC_ACTIVE_KEY) &&
5488 priv->sec.active_key != sec->active_key) {
5489 if (sec->active_key <= 3) {
5490 priv->sec.active_key = sec->active_key;
5491 priv->sec.flags |= SEC_ACTIVE_KEY;
5492 } else
5493 priv->sec.flags &= ~SEC_ACTIVE_KEY;
5494
5495 priv->status |= STATUS_SECURITY_UPDATED;
5496 }
5497
5498 if ((sec->flags & SEC_AUTH_MODE) &&
5499 (priv->sec.auth_mode != sec->auth_mode)) {
5500 priv->sec.auth_mode = sec->auth_mode;
5501 priv->sec.flags |= SEC_AUTH_MODE;
5502 priv->status |= STATUS_SECURITY_UPDATED;
5503 }
5504
5505 if (sec->flags & SEC_ENABLED &&
5506 priv->sec.enabled != sec->enabled) {
5507 priv->sec.flags |= SEC_ENABLED;
5508 priv->sec.enabled = sec->enabled;
5509 priv->status |= STATUS_SECURITY_UPDATED;
5510 force_update = 1;
5511 }
5512
5513 if (sec->flags & SEC_LEVEL &&
5514 priv->sec.level != sec->level) {
5515 priv->sec.level = sec->level;
5516 priv->sec.flags |= SEC_LEVEL;
5517 priv->status |= STATUS_SECURITY_UPDATED;
5518 }
5519
5520 IPW_DEBUG_WEP("Security flags: %c %c%c%c%c %c%c%c%c\n",
5521 priv->sec.flags & (1<<8) ? '1' : '0',
5522 priv->sec.flags & (1<<7) ? '1' : '0',
5523 priv->sec.flags & (1<<6) ? '1' : '0',
5524 priv->sec.flags & (1<<5) ? '1' : '0',
5525 priv->sec.flags & (1<<4) ? '1' : '0',
5526 priv->sec.flags & (1<<3) ? '1' : '0',
5527 priv->sec.flags & (1<<2) ? '1' : '0',
5528 priv->sec.flags & (1<<1) ? '1' : '0',
5529 priv->sec.flags & (1<<0) ? '1' : '0');
5530
5531/* As a temporary work around to enable WPA until we figure out why
5532 * wpa_supplicant toggles the security capability of the driver, which
5533 * forces a disassocation with force_update...
5534 *
5535 * if (force_update || !(priv->status & STATUS_ASSOCIATED))*/
5536 if (!(priv->status & (STATUS_ASSOCIATED | STATUS_ASSOCIATING)))
5537 ipw2100_configure_security(priv, 0);
5538done:
5539 up(&priv->action_sem);
5540}
5541
5542static int ipw2100_adapter_setup(struct ipw2100_priv *priv)
5543{
5544 int err;
5545 int batch_mode = 1;
5546 u8 *bssid;
5547
5548 IPW_DEBUG_INFO("enter\n");
5549
5550 err = ipw2100_disable_adapter(priv);
5551 if (err)
5552 return err;
5553#ifdef CONFIG_IPW2100_MONITOR
5554 if (priv->ieee->iw_mode == IW_MODE_MONITOR) {
5555 err = ipw2100_set_channel(priv, priv->channel, batch_mode);
5556 if (err)
5557 return err;
5558
5559 IPW_DEBUG_INFO("exit\n");
5560
5561 return 0;
5562 }
5563#endif /* CONFIG_IPW2100_MONITOR */
5564
5565 err = ipw2100_read_mac_address(priv);
5566 if (err)
5567 return -EIO;
5568
5569 err = ipw2100_set_mac_address(priv, batch_mode);
5570 if (err)
5571 return err;
5572
5573 err = ipw2100_set_port_type(priv, priv->ieee->iw_mode, batch_mode);
5574 if (err)
5575 return err;
5576
5577 if (priv->ieee->iw_mode == IW_MODE_ADHOC) {
5578 err = ipw2100_set_channel(priv, priv->channel, batch_mode);
5579 if (err)
5580 return err;
5581 }
5582
5583 err = ipw2100_system_config(priv, batch_mode);
5584 if (err)
5585 return err;
5586
5587 err = ipw2100_set_tx_rates(priv, priv->tx_rates, batch_mode);
5588 if (err)
5589 return err;
5590
5591 /* Default to power mode OFF */
5592 err = ipw2100_set_power_mode(priv, IPW_POWER_MODE_CAM);
5593 if (err)
5594 return err;
5595
5596 err = ipw2100_set_rts_threshold(priv, priv->rts_threshold);
5597 if (err)
5598 return err;
5599
5600 if (priv->config & CFG_STATIC_BSSID)
5601 bssid = priv->bssid;
5602 else
5603 bssid = NULL;
5604 err = ipw2100_set_mandatory_bssid(priv, bssid, batch_mode);
5605 if (err)
5606 return err;
5607
5608 if (priv->config & CFG_STATIC_ESSID)
5609 err = ipw2100_set_essid(priv, priv->essid, priv->essid_len,
5610 batch_mode);
5611 else
5612 err = ipw2100_set_essid(priv, NULL, 0, batch_mode);
5613 if (err)
5614 return err;
5615
5616 err = ipw2100_configure_security(priv, batch_mode);
5617 if (err)
5618 return err;
5619
5620 if (priv->ieee->iw_mode == IW_MODE_ADHOC) {
5621 err = ipw2100_set_ibss_beacon_interval(
5622 priv, priv->beacon_interval, batch_mode);
5623 if (err)
5624 return err;
5625
5626 err = ipw2100_set_tx_power(priv, priv->tx_power);
5627 if (err)
5628 return err;
5629 }
5630
5631 /*
5632 err = ipw2100_set_fragmentation_threshold(
5633 priv, priv->frag_threshold, batch_mode);
5634 if (err)
5635 return err;
5636 */
5637
5638 IPW_DEBUG_INFO("exit\n");
5639
5640 return 0;
5641}
5642
5643
5644/*************************************************************************
5645 *
5646 * EXTERNALLY CALLED METHODS
5647 *
5648 *************************************************************************/
5649
5650/* This method is called by the network layer -- not to be confused with
5651 * ipw2100_set_mac_address() declared above called by this driver (and this
5652 * method as well) to talk to the firmware */
5653static int ipw2100_set_address(struct net_device *dev, void *p)
5654{
5655 struct ipw2100_priv *priv = ieee80211_priv(dev);
5656 struct sockaddr *addr = p;
5657 int err = 0;
5658
5659 if (!is_valid_ether_addr(addr->sa_data))
5660 return -EADDRNOTAVAIL;
5661
5662 down(&priv->action_sem);
5663
5664 priv->config |= CFG_CUSTOM_MAC;
5665 memcpy(priv->mac_addr, addr->sa_data, ETH_ALEN);
5666
5667 err = ipw2100_set_mac_address(priv, 0);
5668 if (err)
5669 goto done;
5670
5671 priv->reset_backoff = 0;
5672 up(&priv->action_sem);
5673 ipw2100_reset_adapter(priv);
5674 return 0;
5675
5676 done:
5677 up(&priv->action_sem);
5678 return err;
5679}
5680
5681static int ipw2100_open(struct net_device *dev)
5682{
5683 struct ipw2100_priv *priv = ieee80211_priv(dev);
5684 unsigned long flags;
5685 IPW_DEBUG_INFO("dev->open\n");
5686
5687 spin_lock_irqsave(&priv->low_lock, flags);
5688 if (priv->status & STATUS_ASSOCIATED) {
5689 netif_carrier_on(dev);
5690 netif_start_queue(dev);
5691 }
5692 spin_unlock_irqrestore(&priv->low_lock, flags);
5693
5694 return 0;
5695}
5696
5697static int ipw2100_close(struct net_device *dev)
5698{
5699 struct ipw2100_priv *priv = ieee80211_priv(dev);
5700 unsigned long flags;
5701 struct list_head *element;
5702 struct ipw2100_tx_packet *packet;
5703
5704 IPW_DEBUG_INFO("enter\n");
5705
5706 spin_lock_irqsave(&priv->low_lock, flags);
5707
5708 if (priv->status & STATUS_ASSOCIATED)
5709 netif_carrier_off(dev);
5710 netif_stop_queue(dev);
5711
5712 /* Flush the TX queue ... */
5713 while (!list_empty(&priv->tx_pend_list)) {
5714 element = priv->tx_pend_list.next;
5715 packet = list_entry(element, struct ipw2100_tx_packet, list);
5716
5717 list_del(element);
5718 DEC_STAT(&priv->tx_pend_stat);
5719
5720 ieee80211_txb_free(packet->info.d_struct.txb);
5721 packet->info.d_struct.txb = NULL;
5722
5723 list_add_tail(element, &priv->tx_free_list);
5724 INC_STAT(&priv->tx_free_stat);
5725 }
5726 spin_unlock_irqrestore(&priv->low_lock, flags);
5727
5728 IPW_DEBUG_INFO("exit\n");
5729
5730 return 0;
5731}
5732
5733
5734
5735/*
5736 * TODO: Fix this function... its just wrong
5737 */
5738static void ipw2100_tx_timeout(struct net_device *dev)
5739{
5740 struct ipw2100_priv *priv = ieee80211_priv(dev);
5741
5742 priv->ieee->stats.tx_errors++;
5743
5744#ifdef CONFIG_IPW2100_MONITOR
5745 if (priv->ieee->iw_mode == IW_MODE_MONITOR)
5746 return;
5747#endif
5748
5749 IPW_DEBUG_INFO("%s: TX timed out. Scheduling firmware restart.\n",
5750 dev->name);
5751 schedule_reset(priv);
5752}
5753
5754
5755/*
5756 * TODO: reimplement it so that it reads statistics
5757 * from the adapter using ordinal tables
5758 * instead of/in addition to collecting them
5759 * in the driver
5760 */
5761static struct net_device_stats *ipw2100_stats(struct net_device *dev)
5762{
5763 struct ipw2100_priv *priv = ieee80211_priv(dev);
5764
5765 return &priv->ieee->stats;
5766}
5767
5768/* Support for wpa_supplicant. Will be replaced with WEXT once
5769 * they get WPA support. */
5770#ifdef CONFIG_IEEE80211_WPA
5771
5772/* following definitions must match definitions in driver_ipw2100.c */
5773
5774#define IPW2100_IOCTL_WPA_SUPPLICANT SIOCIWFIRSTPRIV+30
5775
5776#define IPW2100_CMD_SET_WPA_PARAM 1
5777#define IPW2100_CMD_SET_WPA_IE 2
5778#define IPW2100_CMD_SET_ENCRYPTION 3
5779#define IPW2100_CMD_MLME 4
5780
5781#define IPW2100_PARAM_WPA_ENABLED 1
5782#define IPW2100_PARAM_TKIP_COUNTERMEASURES 2
5783#define IPW2100_PARAM_DROP_UNENCRYPTED 3
5784#define IPW2100_PARAM_PRIVACY_INVOKED 4
5785#define IPW2100_PARAM_AUTH_ALGS 5
5786#define IPW2100_PARAM_IEEE_802_1X 6
5787
5788#define IPW2100_MLME_STA_DEAUTH 1
5789#define IPW2100_MLME_STA_DISASSOC 2
5790
5791#define IPW2100_CRYPT_ERR_UNKNOWN_ALG 2
5792#define IPW2100_CRYPT_ERR_UNKNOWN_ADDR 3
5793#define IPW2100_CRYPT_ERR_CRYPT_INIT_FAILED 4
5794#define IPW2100_CRYPT_ERR_KEY_SET_FAILED 5
5795#define IPW2100_CRYPT_ERR_TX_KEY_SET_FAILED 6
5796#define IPW2100_CRYPT_ERR_CARD_CONF_FAILED 7
5797
5798#define IPW2100_CRYPT_ALG_NAME_LEN 16
5799
5800struct ipw2100_param {
5801 u32 cmd;
5802 u8 sta_addr[ETH_ALEN];
5803 union {
5804 struct {
5805 u8 name;
5806 u32 value;
5807 } wpa_param;
5808 struct {
5809 u32 len;
5810 u8 *data;
5811 } wpa_ie;
5812 struct{
5813 int command;
5814 int reason_code;
5815 } mlme;
5816 struct {
5817 u8 alg[IPW2100_CRYPT_ALG_NAME_LEN];
5818 u8 set_tx;
5819 u32 err;
5820 u8 idx;
5821 u8 seq[8]; /* sequence counter (set: RX, get: TX) */
5822 u16 key_len;
5823 u8 key[0];
5824 } crypt;
5825
5826 } u;
5827};
5828
5829/* end of driver_ipw2100.c code */
5830
5831static int ipw2100_wpa_enable(struct ipw2100_priv *priv, int value){
5832
5833 struct ieee80211_device *ieee = priv->ieee;
5834 struct ieee80211_security sec = {
5835 .flags = SEC_LEVEL | SEC_ENABLED,
5836 };
5837 int ret = 0;
5838
5839 ieee->wpa_enabled = value;
5840
5841 if (value){
5842 sec.level = SEC_LEVEL_3;
5843 sec.enabled = 1;
5844 } else {
5845 sec.level = SEC_LEVEL_0;
5846 sec.enabled = 0;
5847 }
5848
5849 if (ieee->set_security)
5850 ieee->set_security(ieee->dev, &sec);
5851 else
5852 ret = -EOPNOTSUPP;
5853
5854 return ret;
5855}
5856
5857#define AUTH_ALG_OPEN_SYSTEM 0x1
5858#define AUTH_ALG_SHARED_KEY 0x2
5859
5860static int ipw2100_wpa_set_auth_algs(struct ipw2100_priv *priv, int value){
5861
5862 struct ieee80211_device *ieee = priv->ieee;
5863 struct ieee80211_security sec = {
5864 .flags = SEC_AUTH_MODE,
5865 };
5866 int ret = 0;
5867
5868 if (value & AUTH_ALG_SHARED_KEY){
5869 sec.auth_mode = WLAN_AUTH_SHARED_KEY;
5870 ieee->open_wep = 0;
5871 } else {
5872 sec.auth_mode = WLAN_AUTH_OPEN;
5873 ieee->open_wep = 1;
5874 }
5875
5876 if (ieee->set_security)
5877 ieee->set_security(ieee->dev, &sec);
5878 else
5879 ret = -EOPNOTSUPP;
5880
5881 return ret;
5882}
5883
5884
5885static int ipw2100_wpa_set_param(struct net_device *dev, u8 name, u32 value){
5886
5887 struct ipw2100_priv *priv = ieee80211_priv(dev);
5888 int ret=0;
5889
5890 switch(name){
5891 case IPW2100_PARAM_WPA_ENABLED:
5892 ret = ipw2100_wpa_enable(priv, value);
5893 break;
5894
5895 case IPW2100_PARAM_TKIP_COUNTERMEASURES:
5896 priv->ieee->tkip_countermeasures=value;
5897 break;
5898
5899 case IPW2100_PARAM_DROP_UNENCRYPTED:
5900 priv->ieee->drop_unencrypted=value;
5901 break;
5902
5903 case IPW2100_PARAM_PRIVACY_INVOKED:
5904 priv->ieee->privacy_invoked=value;
5905 break;
5906
5907 case IPW2100_PARAM_AUTH_ALGS:
5908 ret = ipw2100_wpa_set_auth_algs(priv, value);
5909 break;
5910
5911 case IPW2100_PARAM_IEEE_802_1X:
5912 priv->ieee->ieee802_1x=value;
5913 break;
5914
5915 default:
5916 printk(KERN_ERR DRV_NAME ": %s: Unknown WPA param: %d\n",
5917 dev->name, name);
5918 ret = -EOPNOTSUPP;
5919 }
5920
5921 return ret;
5922}
5923
5924static int ipw2100_wpa_mlme(struct net_device *dev, int command, int reason){
5925
5926 struct ipw2100_priv *priv = ieee80211_priv(dev);
5927 int ret=0;
5928
5929 switch(command){
5930 case IPW2100_MLME_STA_DEAUTH:
5931 // silently ignore
5932 break;
5933
5934 case IPW2100_MLME_STA_DISASSOC:
5935 ipw2100_disassociate_bssid(priv);
5936 break;
5937
5938 default:
5939 printk(KERN_ERR DRV_NAME ": %s: Unknown MLME request: %d\n",
5940 dev->name, command);
5941 ret = -EOPNOTSUPP;
5942 }
5943
5944 return ret;
5945}
5946
5947
5948void ipw2100_wpa_assoc_frame(struct ipw2100_priv *priv,
5949 char *wpa_ie, int wpa_ie_len){
5950
5951 struct ipw2100_wpa_assoc_frame frame;
5952
5953 frame.fixed_ie_mask = 0;
5954
5955 /* copy WPA IE */
5956 memcpy(frame.var_ie, wpa_ie, wpa_ie_len);
5957 frame.var_ie_len = wpa_ie_len;
5958
5959 /* make sure WPA is enabled */
5960 ipw2100_wpa_enable(priv, 1);
5961 ipw2100_set_wpa_ie(priv, &frame, 0);
5962}
5963
5964
5965static int ipw2100_wpa_set_wpa_ie(struct net_device *dev,
5966 struct ipw2100_param *param, int plen){
5967
5968 struct ipw2100_priv *priv = ieee80211_priv(dev);
5969 struct ieee80211_device *ieee = priv->ieee;
5970 u8 *buf;
5971
5972 if (! ieee->wpa_enabled)
5973 return -EOPNOTSUPP;
5974
5975 if (param->u.wpa_ie.len > MAX_WPA_IE_LEN ||
5976 (param->u.wpa_ie.len &&
5977 param->u.wpa_ie.data==NULL))
5978 return -EINVAL;
5979
5980 if (param->u.wpa_ie.len){
5981 buf = kmalloc(param->u.wpa_ie.len, GFP_KERNEL);
5982 if (buf == NULL)
5983 return -ENOMEM;
5984
5985 memcpy(buf, param->u.wpa_ie.data, param->u.wpa_ie.len);
5986
5987 kfree(ieee->wpa_ie);
5988 ieee->wpa_ie = buf;
5989 ieee->wpa_ie_len = param->u.wpa_ie.len;
5990
5991 } else {
5992 kfree(ieee->wpa_ie);
5993 ieee->wpa_ie = NULL;
5994 ieee->wpa_ie_len = 0;
5995 }
5996
5997 ipw2100_wpa_assoc_frame(priv, ieee->wpa_ie, ieee->wpa_ie_len);
5998
5999 return 0;
6000}
6001
6002/* implementation borrowed from hostap driver */
6003
6004static int ipw2100_wpa_set_encryption(struct net_device *dev,
6005 struct ipw2100_param *param, int param_len){
6006
6007 int ret = 0;
6008 struct ipw2100_priv *priv = ieee80211_priv(dev);
6009 struct ieee80211_device *ieee = priv->ieee;
6010 struct ieee80211_crypto_ops *ops;
6011 struct ieee80211_crypt_data **crypt;
6012
6013 struct ieee80211_security sec = {
6014 .flags = 0,
6015 };
6016
6017 param->u.crypt.err = 0;
6018 param->u.crypt.alg[IPW2100_CRYPT_ALG_NAME_LEN - 1] = '\0';
6019
6020 if (param_len !=
6021 (int) ((char *) param->u.crypt.key - (char *) param) +
6022 param->u.crypt.key_len){
6023 IPW_DEBUG_INFO("Len mismatch %d, %d\n", param_len, param->u.crypt.key_len);
6024 return -EINVAL;
6025 }
6026 if (param->sta_addr[0] == 0xff && param->sta_addr[1] == 0xff &&
6027 param->sta_addr[2] == 0xff && param->sta_addr[3] == 0xff &&
6028 param->sta_addr[4] == 0xff && param->sta_addr[5] == 0xff) {
6029 if (param->u.crypt.idx >= WEP_KEYS)
6030 return -EINVAL;
6031 crypt = &ieee->crypt[param->u.crypt.idx];
6032 } else {
6033 return -EINVAL;
6034 }
6035
6036 if (strcmp(param->u.crypt.alg, "none") == 0) {
6037 if (crypt){
6038 sec.enabled = 0;
6039 sec.level = SEC_LEVEL_0;
6040 sec.flags |= SEC_ENABLED | SEC_LEVEL;
6041 ieee80211_crypt_delayed_deinit(ieee, crypt);
6042 }
6043 goto done;
6044 }
6045 sec.enabled = 1;
6046 sec.flags |= SEC_ENABLED;
6047
6048 ops = ieee80211_get_crypto_ops(param->u.crypt.alg);
6049 if (ops == NULL && strcmp(param->u.crypt.alg, "WEP") == 0) {
6050 request_module("ieee80211_crypt_wep");
6051 ops = ieee80211_get_crypto_ops(param->u.crypt.alg);
6052 } else if (ops == NULL && strcmp(param->u.crypt.alg, "TKIP") == 0) {
6053 request_module("ieee80211_crypt_tkip");
6054 ops = ieee80211_get_crypto_ops(param->u.crypt.alg);
6055 } else if (ops == NULL && strcmp(param->u.crypt.alg, "CCMP") == 0) {
6056 request_module("ieee80211_crypt_ccmp");
6057 ops = ieee80211_get_crypto_ops(param->u.crypt.alg);
6058 }
6059 if (ops == NULL) {
6060 IPW_DEBUG_INFO("%s: unknown crypto alg '%s'\n",
6061 dev->name, param->u.crypt.alg);
6062 param->u.crypt.err = IPW2100_CRYPT_ERR_UNKNOWN_ALG;
6063 ret = -EINVAL;
6064 goto done;
6065 }
6066
6067 if (*crypt == NULL || (*crypt)->ops != ops) {
6068 struct ieee80211_crypt_data *new_crypt;
6069
6070 ieee80211_crypt_delayed_deinit(ieee, crypt);
6071
6072 new_crypt = (struct ieee80211_crypt_data *)
6073 kmalloc(sizeof(struct ieee80211_crypt_data), GFP_KERNEL);
6074 if (new_crypt == NULL) {
6075 ret = -ENOMEM;
6076 goto done;
6077 }
6078 memset(new_crypt, 0, sizeof(struct ieee80211_crypt_data));
6079 new_crypt->ops = ops;
6080 if (new_crypt->ops && try_module_get(new_crypt->ops->owner))
6081 new_crypt->priv = new_crypt->ops->init(param->u.crypt.idx);
6082
6083 if (new_crypt->priv == NULL) {
6084 kfree(new_crypt);
6085 param->u.crypt.err =
6086 IPW2100_CRYPT_ERR_CRYPT_INIT_FAILED;
6087 ret = -EINVAL;
6088 goto done;
6089 }
6090
6091 *crypt = new_crypt;
6092 }
6093
6094 if (param->u.crypt.key_len > 0 && (*crypt)->ops->set_key &&
6095 (*crypt)->ops->set_key(param->u.crypt.key,
6096 param->u.crypt.key_len, param->u.crypt.seq,
6097 (*crypt)->priv) < 0) {
6098 IPW_DEBUG_INFO("%s: key setting failed\n",
6099 dev->name);
6100 param->u.crypt.err = IPW2100_CRYPT_ERR_KEY_SET_FAILED;
6101 ret = -EINVAL;
6102 goto done;
6103 }
6104
6105 if (param->u.crypt.set_tx){
6106 ieee->tx_keyidx = param->u.crypt.idx;
6107 sec.active_key = param->u.crypt.idx;
6108 sec.flags |= SEC_ACTIVE_KEY;
6109 }
6110
6111 if (ops->name != NULL){
6112
6113 if (strcmp(ops->name, "WEP") == 0) {
6114 memcpy(sec.keys[param->u.crypt.idx], param->u.crypt.key, param->u.crypt.key_len);
6115 sec.key_sizes[param->u.crypt.idx] = param->u.crypt.key_len;
6116 sec.flags |= (1 << param->u.crypt.idx);
6117 sec.flags |= SEC_LEVEL;
6118 sec.level = SEC_LEVEL_1;
6119 } else if (strcmp(ops->name, "TKIP") == 0) {
6120 sec.flags |= SEC_LEVEL;
6121 sec.level = SEC_LEVEL_2;
6122 } else if (strcmp(ops->name, "CCMP") == 0) {
6123 sec.flags |= SEC_LEVEL;
6124 sec.level = SEC_LEVEL_3;
6125 }
6126 }
6127 done:
6128 if (ieee->set_security)
6129 ieee->set_security(ieee->dev, &sec);
6130
6131 /* Do not reset port if card is in Managed mode since resetting will
6132 * generate new IEEE 802.11 authentication which may end up in looping
6133 * with IEEE 802.1X. If your hardware requires a reset after WEP
6134 * configuration (for example... Prism2), implement the reset_port in
6135 * the callbacks structures used to initialize the 802.11 stack. */
6136 if (ieee->reset_on_keychange &&
6137 ieee->iw_mode != IW_MODE_INFRA &&
6138 ieee->reset_port &&
6139 ieee->reset_port(dev)) {
6140 IPW_DEBUG_INFO("%s: reset_port failed\n", dev->name);
6141 param->u.crypt.err = IPW2100_CRYPT_ERR_CARD_CONF_FAILED;
6142 return -EINVAL;
6143 }
6144
6145 return ret;
6146}
6147
6148
6149static int ipw2100_wpa_supplicant(struct net_device *dev, struct iw_point *p){
6150
6151 struct ipw2100_param *param;
6152 int ret=0;
6153
6154 IPW_DEBUG_IOCTL("wpa_supplicant: len=%d\n", p->length);
6155
6156 if (p->length < sizeof(struct ipw2100_param) || !p->pointer)
6157 return -EINVAL;
6158
6159 param = (struct ipw2100_param *)kmalloc(p->length, GFP_KERNEL);
6160 if (param == NULL)
6161 return -ENOMEM;
6162
6163 if (copy_from_user(param, p->pointer, p->length)){
6164 kfree(param);
6165 return -EFAULT;
6166 }
6167
6168 switch (param->cmd){
6169
6170 case IPW2100_CMD_SET_WPA_PARAM:
6171 ret = ipw2100_wpa_set_param(dev, param->u.wpa_param.name,
6172 param->u.wpa_param.value);
6173 break;
6174
6175 case IPW2100_CMD_SET_WPA_IE:
6176 ret = ipw2100_wpa_set_wpa_ie(dev, param, p->length);
6177 break;
6178
6179 case IPW2100_CMD_SET_ENCRYPTION:
6180 ret = ipw2100_wpa_set_encryption(dev, param, p->length);
6181 break;
6182
6183 case IPW2100_CMD_MLME:
6184 ret = ipw2100_wpa_mlme(dev, param->u.mlme.command,
6185 param->u.mlme.reason_code);
6186 break;
6187
6188 default:
6189 printk(KERN_ERR DRV_NAME ": %s: Unknown WPA supplicant request: %d\n",
6190 dev->name, param->cmd);
6191 ret = -EOPNOTSUPP;
6192
6193 }
6194
6195 if (ret == 0 && copy_to_user(p->pointer, param, p->length))
6196 ret = -EFAULT;
6197
6198 kfree(param);
6199 return ret;
6200}
6201#endif /* CONFIG_IEEE80211_WPA */
6202
6203static int ipw2100_ioctl(struct net_device *dev, struct ifreq *rq, int cmd)
6204{
6205#ifdef CONFIG_IEEE80211_WPA
6206 struct iwreq *wrq = (struct iwreq *) rq;
6207 int ret=-1;
6208 switch (cmd){
6209 case IPW2100_IOCTL_WPA_SUPPLICANT:
6210 ret = ipw2100_wpa_supplicant(dev, &wrq->u.data);
6211 return ret;
6212
6213 default:
6214 return -EOPNOTSUPP;
6215 }
6216
6217#endif /* CONFIG_IEEE80211_WPA */
6218
6219 return -EOPNOTSUPP;
6220}
6221
6222
6223static void ipw_ethtool_get_drvinfo(struct net_device *dev,
6224 struct ethtool_drvinfo *info)
6225{
6226 struct ipw2100_priv *priv = ieee80211_priv(dev);
6227 char fw_ver[64], ucode_ver[64];
6228
6229 strcpy(info->driver, DRV_NAME);
6230 strcpy(info->version, DRV_VERSION);
6231
6232 ipw2100_get_fwversion(priv, fw_ver, sizeof(fw_ver));
6233 ipw2100_get_ucodeversion(priv, ucode_ver, sizeof(ucode_ver));
6234
6235 snprintf(info->fw_version, sizeof(info->fw_version), "%s:%d:%s",
6236 fw_ver, priv->eeprom_version, ucode_ver);
6237
6238 strcpy(info->bus_info, pci_name(priv->pci_dev));
6239}
6240
6241static u32 ipw2100_ethtool_get_link(struct net_device *dev)
6242{
6243 struct ipw2100_priv *priv = ieee80211_priv(dev);
6244 return (priv->status & STATUS_ASSOCIATED) ? 1 : 0;
6245}
6246
6247
6248static struct ethtool_ops ipw2100_ethtool_ops = {
6249 .get_link = ipw2100_ethtool_get_link,
6250 .get_drvinfo = ipw_ethtool_get_drvinfo,
6251};
6252
6253static void ipw2100_hang_check(void *adapter)
6254{
6255 struct ipw2100_priv *priv = adapter;
6256 unsigned long flags;
6257 u32 rtc = 0xa5a5a5a5;
6258 u32 len = sizeof(rtc);
6259 int restart = 0;
6260
6261 spin_lock_irqsave(&priv->low_lock, flags);
6262
6263 if (priv->fatal_error != 0) {
6264 /* If fatal_error is set then we need to restart */
6265 IPW_DEBUG_INFO("%s: Hardware fatal error detected.\n",
6266 priv->net_dev->name);
6267
6268 restart = 1;
6269 } else if (ipw2100_get_ordinal(priv, IPW_ORD_RTC_TIME, &rtc, &len) ||
6270 (rtc == priv->last_rtc)) {
6271 /* Check if firmware is hung */
6272 IPW_DEBUG_INFO("%s: Firmware RTC stalled.\n",
6273 priv->net_dev->name);
6274
6275 restart = 1;
6276 }
6277
6278 if (restart) {
6279 /* Kill timer */
6280 priv->stop_hang_check = 1;
6281 priv->hangs++;
6282
6283 /* Restart the NIC */
6284 schedule_reset(priv);
6285 }
6286
6287 priv->last_rtc = rtc;
6288
6289 if (!priv->stop_hang_check)
6290 queue_delayed_work(priv->workqueue, &priv->hang_check, HZ / 2);
6291
6292 spin_unlock_irqrestore(&priv->low_lock, flags);
6293}
6294
6295
6296static void ipw2100_rf_kill(void *adapter)
6297{
6298 struct ipw2100_priv *priv = adapter;
6299 unsigned long flags;
6300
6301 spin_lock_irqsave(&priv->low_lock, flags);
6302
6303 if (rf_kill_active(priv)) {
6304 IPW_DEBUG_RF_KILL("RF Kill active, rescheduling GPIO check\n");
6305 if (!priv->stop_rf_kill)
6306 queue_delayed_work(priv->workqueue, &priv->rf_kill, HZ);
6307 goto exit_unlock;
6308 }
6309
6310 /* RF Kill is now disabled, so bring the device back up */
6311
6312 if (!(priv->status & STATUS_RF_KILL_MASK)) {
6313 IPW_DEBUG_RF_KILL("HW RF Kill no longer active, restarting "
6314 "device\n");
6315 schedule_reset(priv);
6316 } else
6317 IPW_DEBUG_RF_KILL("HW RF Kill deactivated. SW RF Kill still "
6318 "enabled\n");
6319
6320 exit_unlock:
6321 spin_unlock_irqrestore(&priv->low_lock, flags);
6322}
6323
6324static void ipw2100_irq_tasklet(struct ipw2100_priv *priv);
6325
6326/* Look into using netdev destructor to shutdown ieee80211? */
6327
6328static struct net_device *ipw2100_alloc_device(
6329 struct pci_dev *pci_dev,
6330 char *base_addr,
6331 unsigned long mem_start,
6332 unsigned long mem_len)
6333{
6334 struct ipw2100_priv *priv;
6335 struct net_device *dev;
6336
6337 dev = alloc_ieee80211(sizeof(struct ipw2100_priv));
6338 if (!dev)
6339 return NULL;
6340 priv = ieee80211_priv(dev);
6341 priv->ieee = netdev_priv(dev);
6342 priv->pci_dev = pci_dev;
6343 priv->net_dev = dev;
6344
6345 priv->ieee->hard_start_xmit = ipw2100_tx;
6346 priv->ieee->set_security = shim__set_security;
6347
6348 dev->open = ipw2100_open;
6349 dev->stop = ipw2100_close;
6350 dev->init = ipw2100_net_init;
6351 dev->do_ioctl = ipw2100_ioctl;
6352 dev->get_stats = ipw2100_stats;
6353 dev->ethtool_ops = &ipw2100_ethtool_ops;
6354 dev->tx_timeout = ipw2100_tx_timeout;
6355 dev->wireless_handlers = &ipw2100_wx_handler_def;
6356 dev->get_wireless_stats = ipw2100_wx_wireless_stats;
6357 dev->set_mac_address = ipw2100_set_address;
6358 dev->watchdog_timeo = 3*HZ;
6359 dev->irq = 0;
6360
6361 dev->base_addr = (unsigned long)base_addr;
6362 dev->mem_start = mem_start;
6363 dev->mem_end = dev->mem_start + mem_len - 1;
6364
6365 /* NOTE: We don't use the wireless_handlers hook
6366 * in dev as the system will start throwing WX requests
6367 * to us before we're actually initialized and it just
6368 * ends up causing problems. So, we just handle
6369 * the WX extensions through the ipw2100_ioctl interface */
6370
6371
6372 /* memset() puts everything to 0, so we only have explicitely set
6373 * those values that need to be something else */
6374
6375 /* If power management is turned on, default to AUTO mode */
6376 priv->power_mode = IPW_POWER_AUTO;
6377
6378
6379
6380#ifdef CONFIG_IEEE80211_WPA
6381 priv->ieee->wpa_enabled = 0;
6382 priv->ieee->tkip_countermeasures = 0;
6383 priv->ieee->drop_unencrypted = 0;
6384 priv->ieee->privacy_invoked = 0;
6385 priv->ieee->ieee802_1x = 1;
6386#endif /* CONFIG_IEEE80211_WPA */
6387
6388 /* Set module parameters */
6389 switch (mode) {
6390 case 1:
6391 priv->ieee->iw_mode = IW_MODE_ADHOC;
6392 break;
6393#ifdef CONFIG_IPW2100_MONITOR
6394 case 2:
6395 priv->ieee->iw_mode = IW_MODE_MONITOR;
6396 break;
6397#endif
6398 default:
6399 case 0:
6400 priv->ieee->iw_mode = IW_MODE_INFRA;
6401 break;
6402 }
6403
6404 if (disable == 1)
6405 priv->status |= STATUS_RF_KILL_SW;
6406
6407 if (channel != 0 &&
6408 ((channel >= REG_MIN_CHANNEL) &&
6409 (channel <= REG_MAX_CHANNEL))) {
6410 priv->config |= CFG_STATIC_CHANNEL;
6411 priv->channel = channel;
6412 }
6413
6414 if (associate)
6415 priv->config |= CFG_ASSOCIATE;
6416
6417 priv->beacon_interval = DEFAULT_BEACON_INTERVAL;
6418 priv->short_retry_limit = DEFAULT_SHORT_RETRY_LIMIT;
6419 priv->long_retry_limit = DEFAULT_LONG_RETRY_LIMIT;
6420 priv->rts_threshold = DEFAULT_RTS_THRESHOLD | RTS_DISABLED;
6421 priv->frag_threshold = DEFAULT_FTS | FRAG_DISABLED;
6422 priv->tx_power = IPW_TX_POWER_DEFAULT;
6423 priv->tx_rates = DEFAULT_TX_RATES;
6424
6425 strcpy(priv->nick, "ipw2100");
6426
6427 spin_lock_init(&priv->low_lock);
6428 sema_init(&priv->action_sem, 1);
6429 sema_init(&priv->adapter_sem, 1);
6430
6431 init_waitqueue_head(&priv->wait_command_queue);
6432
6433 netif_carrier_off(dev);
6434
6435 INIT_LIST_HEAD(&priv->msg_free_list);
6436 INIT_LIST_HEAD(&priv->msg_pend_list);
6437 INIT_STAT(&priv->msg_free_stat);
6438 INIT_STAT(&priv->msg_pend_stat);
6439
6440 INIT_LIST_HEAD(&priv->tx_free_list);
6441 INIT_LIST_HEAD(&priv->tx_pend_list);
6442 INIT_STAT(&priv->tx_free_stat);
6443 INIT_STAT(&priv->tx_pend_stat);
6444
6445 INIT_LIST_HEAD(&priv->fw_pend_list);
6446 INIT_STAT(&priv->fw_pend_stat);
6447
6448
6449#ifdef CONFIG_SOFTWARE_SUSPEND2
6450 priv->workqueue = create_workqueue(DRV_NAME, 0);
6451#else
6452 priv->workqueue = create_workqueue(DRV_NAME);
6453#endif
6454 INIT_WORK(&priv->reset_work,
6455 (void (*)(void *))ipw2100_reset_adapter, priv);
6456 INIT_WORK(&priv->security_work,
6457 (void (*)(void *))ipw2100_security_work, priv);
6458 INIT_WORK(&priv->wx_event_work,
6459 (void (*)(void *))ipw2100_wx_event_work, priv);
6460 INIT_WORK(&priv->hang_check, ipw2100_hang_check, priv);
6461 INIT_WORK(&priv->rf_kill, ipw2100_rf_kill, priv);
6462
6463 tasklet_init(&priv->irq_tasklet, (void (*)(unsigned long))
6464 ipw2100_irq_tasklet, (unsigned long)priv);
6465
6466 /* NOTE: We do not start the deferred work for status checks yet */
6467 priv->stop_rf_kill = 1;
6468 priv->stop_hang_check = 1;
6469
6470 return dev;
6471}
6472
6473static int ipw2100_pci_init_one(struct pci_dev *pci_dev,
6474 const struct pci_device_id *ent)
6475{
6476 unsigned long mem_start, mem_len, mem_flags;
6477 char *base_addr = NULL;
6478 struct net_device *dev = NULL;
6479 struct ipw2100_priv *priv = NULL;
6480 int err = 0;
6481 int registered = 0;
6482 u32 val;
6483
6484 IPW_DEBUG_INFO("enter\n");
6485
6486 mem_start = pci_resource_start(pci_dev, 0);
6487 mem_len = pci_resource_len(pci_dev, 0);
6488 mem_flags = pci_resource_flags(pci_dev, 0);
6489
6490 if ((mem_flags & IORESOURCE_MEM) != IORESOURCE_MEM) {
6491 IPW_DEBUG_INFO("weird - resource type is not memory\n");
6492 err = -ENODEV;
6493 goto fail;
6494 }
6495
6496 base_addr = ioremap_nocache(mem_start, mem_len);
6497 if (!base_addr) {
6498 printk(KERN_WARNING DRV_NAME
6499 "Error calling ioremap_nocache.\n");
6500 err = -EIO;
6501 goto fail;
6502 }
6503
6504 /* allocate and initialize our net_device */
6505 dev = ipw2100_alloc_device(pci_dev, base_addr, mem_start, mem_len);
6506 if (!dev) {
6507 printk(KERN_WARNING DRV_NAME
6508 "Error calling ipw2100_alloc_device.\n");
6509 err = -ENOMEM;
6510 goto fail;
6511 }
6512
6513 /* set up PCI mappings for device */
6514 err = pci_enable_device(pci_dev);
6515 if (err) {
6516 printk(KERN_WARNING DRV_NAME
6517 "Error calling pci_enable_device.\n");
6518 return err;
6519 }
6520
6521 priv = ieee80211_priv(dev);
6522
6523 pci_set_master(pci_dev);
6524 pci_set_drvdata(pci_dev, priv);
6525
6526 err = pci_set_dma_mask(pci_dev, DMA_32BIT_MASK);
6527 if (err) {
6528 printk(KERN_WARNING DRV_NAME
6529 "Error calling pci_set_dma_mask.\n");
6530 pci_disable_device(pci_dev);
6531 return err;
6532 }
6533
6534 err = pci_request_regions(pci_dev, DRV_NAME);
6535 if (err) {
6536 printk(KERN_WARNING DRV_NAME
6537 "Error calling pci_request_regions.\n");
6538 pci_disable_device(pci_dev);
6539 return err;
6540 }
6541
6542 /* We disable the RETRY_TIMEOUT register (0x41) to keep
6543 * PCI Tx retries from interfering with C3 CPU state */
6544 pci_read_config_dword(pci_dev, 0x40, &val);
6545 if ((val & 0x0000ff00) != 0)
6546 pci_write_config_dword(pci_dev, 0x40, val & 0xffff00ff);
6547
6548 pci_set_power_state(pci_dev, PCI_D0);
6549
6550 if (!ipw2100_hw_is_adapter_in_system(dev)) {
6551 printk(KERN_WARNING DRV_NAME
6552 "Device not found via register read.\n");
6553 err = -ENODEV;
6554 goto fail;
6555 }
6556
6557 SET_NETDEV_DEV(dev, &pci_dev->dev);
6558
6559 /* Force interrupts to be shut off on the device */
6560 priv->status |= STATUS_INT_ENABLED;
6561 ipw2100_disable_interrupts(priv);
6562
6563 /* Allocate and initialize the Tx/Rx queues and lists */
6564 if (ipw2100_queues_allocate(priv)) {
6565 printk(KERN_WARNING DRV_NAME
6566 "Error calilng ipw2100_queues_allocate.\n");
6567 err = -ENOMEM;
6568 goto fail;
6569 }
6570 ipw2100_queues_initialize(priv);
6571
6572 err = request_irq(pci_dev->irq,
6573 ipw2100_interrupt, SA_SHIRQ,
6574 dev->name, priv);
6575 if (err) {
6576 printk(KERN_WARNING DRV_NAME
6577 "Error calling request_irq: %d.\n",
6578 pci_dev->irq);
6579 goto fail;
6580 }
6581 dev->irq = pci_dev->irq;
6582
6583 IPW_DEBUG_INFO("Attempting to register device...\n");
6584
6585 SET_MODULE_OWNER(dev);
6586
6587 printk(KERN_INFO DRV_NAME
6588 ": Detected Intel PRO/Wireless 2100 Network Connection\n");
6589
6590 /* Bring up the interface. Pre 0.46, after we registered the
6591 * network device we would call ipw2100_up. This introduced a race
6592 * condition with newer hotplug configurations (network was coming
6593 * up and making calls before the device was initialized).
6594 *
6595 * If we called ipw2100_up before we registered the device, then the
6596 * device name wasn't registered. So, we instead use the net_dev->init
6597 * member to call a function that then just turns and calls ipw2100_up.
6598 * net_dev->init is called after name allocation but before the
6599 * notifier chain is called */
6600 down(&priv->action_sem);
6601 err = register_netdev(dev);
6602 if (err) {
6603 printk(KERN_WARNING DRV_NAME
6604 "Error calling register_netdev.\n");
6605 goto fail_unlock;
6606 }
6607 registered = 1;
6608
6609 IPW_DEBUG_INFO("%s: Bound to %s\n", dev->name, pci_name(pci_dev));
6610
6611 /* perform this after register_netdev so that dev->name is set */
6612 sysfs_create_group(&pci_dev->dev.kobj, &ipw2100_attribute_group);
6613 netif_carrier_off(dev);
6614
6615 /* If the RF Kill switch is disabled, go ahead and complete the
6616 * startup sequence */
6617 if (!(priv->status & STATUS_RF_KILL_MASK)) {
6618 /* Enable the adapter - sends HOST_COMPLETE */
6619 if (ipw2100_enable_adapter(priv)) {
6620 printk(KERN_WARNING DRV_NAME
6621 ": %s: failed in call to enable adapter.\n",
6622 priv->net_dev->name);
6623 ipw2100_hw_stop_adapter(priv);
6624 err = -EIO;
6625 goto fail_unlock;
6626 }
6627
6628 /* Start a scan . . . */
6629 ipw2100_set_scan_options(priv);
6630 ipw2100_start_scan(priv);
6631 }
6632
6633 IPW_DEBUG_INFO("exit\n");
6634
6635 priv->status |= STATUS_INITIALIZED;
6636
6637 up(&priv->action_sem);
6638
6639 return 0;
6640
6641 fail_unlock:
6642 up(&priv->action_sem);
6643
6644 fail:
6645 if (dev) {
6646 if (registered)
6647 unregister_netdev(dev);
6648
6649 ipw2100_hw_stop_adapter(priv);
6650
6651 ipw2100_disable_interrupts(priv);
6652
6653 if (dev->irq)
6654 free_irq(dev->irq, priv);
6655
6656 ipw2100_kill_workqueue(priv);
6657
6658 /* These are safe to call even if they weren't allocated */
6659 ipw2100_queues_free(priv);
6660 sysfs_remove_group(&pci_dev->dev.kobj, &ipw2100_attribute_group);
6661
6662 free_ieee80211(dev);
6663 pci_set_drvdata(pci_dev, NULL);
6664 }
6665
6666 if (base_addr)
6667 iounmap((char*)base_addr);
6668
6669 pci_release_regions(pci_dev);
6670 pci_disable_device(pci_dev);
6671
6672 return err;
6673}
6674
6675static void __devexit ipw2100_pci_remove_one(struct pci_dev *pci_dev)
6676{
6677 struct ipw2100_priv *priv = pci_get_drvdata(pci_dev);
6678 struct net_device *dev;
6679
6680 if (priv) {
6681 down(&priv->action_sem);
6682
6683 priv->status &= ~STATUS_INITIALIZED;
6684
6685 dev = priv->net_dev;
6686 sysfs_remove_group(&pci_dev->dev.kobj, &ipw2100_attribute_group);
6687
6688#ifdef CONFIG_PM
6689 if (ipw2100_firmware.version)
6690 ipw2100_release_firmware(priv, &ipw2100_firmware);
6691#endif
6692 /* Take down the hardware */
6693 ipw2100_down(priv);
6694
6695 /* Release the semaphore so that the network subsystem can
6696 * complete any needed calls into the driver... */
6697 up(&priv->action_sem);
6698
6699 /* Unregister the device first - this results in close()
6700 * being called if the device is open. If we free storage
6701 * first, then close() will crash. */
6702 unregister_netdev(dev);
6703
6704 /* ipw2100_down will ensure that there is no more pending work
6705 * in the workqueue's, so we can safely remove them now. */
6706 ipw2100_kill_workqueue(priv);
6707
6708 ipw2100_queues_free(priv);
6709
6710 /* Free potential debugging firmware snapshot */
6711 ipw2100_snapshot_free(priv);
6712
6713 if (dev->irq)
6714 free_irq(dev->irq, priv);
6715
6716 if (dev->base_addr)
6717 iounmap((unsigned char *)dev->base_addr);
6718
6719 free_ieee80211(dev);
6720 }
6721
6722 pci_release_regions(pci_dev);
6723 pci_disable_device(pci_dev);
6724
6725 IPW_DEBUG_INFO("exit\n");
6726}
6727
6728
6729#ifdef CONFIG_PM
6730#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,11)
6731static int ipw2100_suspend(struct pci_dev *pci_dev, u32 state)
6732#else
6733static int ipw2100_suspend(struct pci_dev *pci_dev, pm_message_t state)
6734#endif
6735{
6736 struct ipw2100_priv *priv = pci_get_drvdata(pci_dev);
6737 struct net_device *dev = priv->net_dev;
6738
6739 IPW_DEBUG_INFO("%s: Going into suspend...\n",
6740 dev->name);
6741
6742 down(&priv->action_sem);
6743 if (priv->status & STATUS_INITIALIZED) {
6744 /* Take down the device; powers it off, etc. */
6745 ipw2100_down(priv);
6746 }
6747
6748 /* Remove the PRESENT state of the device */
6749 netif_device_detach(dev);
6750
6751 pci_save_state(pci_dev);
6752 pci_disable_device (pci_dev);
6753 pci_set_power_state(pci_dev, PCI_D3hot);
6754
6755 up(&priv->action_sem);
6756
6757 return 0;
6758}
6759
6760static int ipw2100_resume(struct pci_dev *pci_dev)
6761{
6762 struct ipw2100_priv *priv = pci_get_drvdata(pci_dev);
6763 struct net_device *dev = priv->net_dev;
6764 u32 val;
6765
6766 if (IPW2100_PM_DISABLED)
6767 return 0;
6768
6769 down(&priv->action_sem);
6770
6771 IPW_DEBUG_INFO("%s: Coming out of suspend...\n",
6772 dev->name);
6773
6774 pci_set_power_state(pci_dev, PCI_D0);
6775 pci_enable_device(pci_dev);
6776 pci_restore_state(pci_dev);
6777
6778 /*
6779 * Suspend/Resume resets the PCI configuration space, so we have to
6780 * re-disable the RETRY_TIMEOUT register (0x41) to keep PCI Tx retries
6781 * from interfering with C3 CPU state. pci_restore_state won't help
6782 * here since it only restores the first 64 bytes pci config header.
6783 */
6784 pci_read_config_dword(pci_dev, 0x40, &val);
6785 if ((val & 0x0000ff00) != 0)
6786 pci_write_config_dword(pci_dev, 0x40, val & 0xffff00ff);
6787
6788 /* Set the device back into the PRESENT state; this will also wake
6789 * the queue of needed */
6790 netif_device_attach(dev);
6791
6792 /* Bring the device back up */
6793 if (!(priv->status & STATUS_RF_KILL_SW))
6794 ipw2100_up(priv, 0);
6795
6796 up(&priv->action_sem);
6797
6798 return 0;
6799}
6800#endif
6801
6802
6803#define IPW2100_DEV_ID(x) { PCI_VENDOR_ID_INTEL, 0x1043, 0x8086, x }
6804
6805static struct pci_device_id ipw2100_pci_id_table[] __devinitdata = {
6806 IPW2100_DEV_ID(0x2520), /* IN 2100A mPCI 3A */
6807 IPW2100_DEV_ID(0x2521), /* IN 2100A mPCI 3B */
6808 IPW2100_DEV_ID(0x2524), /* IN 2100A mPCI 3B */
6809 IPW2100_DEV_ID(0x2525), /* IN 2100A mPCI 3B */
6810 IPW2100_DEV_ID(0x2526), /* IN 2100A mPCI Gen A3 */
6811 IPW2100_DEV_ID(0x2522), /* IN 2100 mPCI 3B */
6812 IPW2100_DEV_ID(0x2523), /* IN 2100 mPCI 3A */
6813 IPW2100_DEV_ID(0x2527), /* IN 2100 mPCI 3B */
6814 IPW2100_DEV_ID(0x2528), /* IN 2100 mPCI 3B */
6815 IPW2100_DEV_ID(0x2529), /* IN 2100 mPCI 3B */
6816 IPW2100_DEV_ID(0x252B), /* IN 2100 mPCI 3A */
6817 IPW2100_DEV_ID(0x252C), /* IN 2100 mPCI 3A */
6818 IPW2100_DEV_ID(0x252D), /* IN 2100 mPCI 3A */
6819
6820 IPW2100_DEV_ID(0x2550), /* IB 2100A mPCI 3B */
6821 IPW2100_DEV_ID(0x2551), /* IB 2100 mPCI 3B */
6822 IPW2100_DEV_ID(0x2553), /* IB 2100 mPCI 3B */
6823 IPW2100_DEV_ID(0x2554), /* IB 2100 mPCI 3B */
6824 IPW2100_DEV_ID(0x2555), /* IB 2100 mPCI 3B */
6825
6826 IPW2100_DEV_ID(0x2560), /* DE 2100A mPCI 3A */
6827 IPW2100_DEV_ID(0x2562), /* DE 2100A mPCI 3A */
6828 IPW2100_DEV_ID(0x2563), /* DE 2100A mPCI 3A */
6829 IPW2100_DEV_ID(0x2561), /* DE 2100 mPCI 3A */
6830 IPW2100_DEV_ID(0x2565), /* DE 2100 mPCI 3A */
6831 IPW2100_DEV_ID(0x2566), /* DE 2100 mPCI 3A */
6832 IPW2100_DEV_ID(0x2567), /* DE 2100 mPCI 3A */
6833
6834 IPW2100_DEV_ID(0x2570), /* GA 2100 mPCI 3B */
6835
6836 IPW2100_DEV_ID(0x2580), /* TO 2100A mPCI 3B */
6837 IPW2100_DEV_ID(0x2582), /* TO 2100A mPCI 3B */
6838 IPW2100_DEV_ID(0x2583), /* TO 2100A mPCI 3B */
6839 IPW2100_DEV_ID(0x2581), /* TO 2100 mPCI 3B */
6840 IPW2100_DEV_ID(0x2585), /* TO 2100 mPCI 3B */
6841 IPW2100_DEV_ID(0x2586), /* TO 2100 mPCI 3B */
6842 IPW2100_DEV_ID(0x2587), /* TO 2100 mPCI 3B */
6843
6844 IPW2100_DEV_ID(0x2590), /* SO 2100A mPCI 3B */
6845 IPW2100_DEV_ID(0x2592), /* SO 2100A mPCI 3B */
6846 IPW2100_DEV_ID(0x2591), /* SO 2100 mPCI 3B */
6847 IPW2100_DEV_ID(0x2593), /* SO 2100 mPCI 3B */
6848 IPW2100_DEV_ID(0x2596), /* SO 2100 mPCI 3B */
6849 IPW2100_DEV_ID(0x2598), /* SO 2100 mPCI 3B */
6850
6851 IPW2100_DEV_ID(0x25A0), /* HP 2100 mPCI 3B */
6852 {0,},
6853};
6854
6855MODULE_DEVICE_TABLE(pci, ipw2100_pci_id_table);
6856
6857static struct pci_driver ipw2100_pci_driver = {
6858 .name = DRV_NAME,
6859 .id_table = ipw2100_pci_id_table,
6860 .probe = ipw2100_pci_init_one,
6861 .remove = __devexit_p(ipw2100_pci_remove_one),
6862#ifdef CONFIG_PM
6863 .suspend = ipw2100_suspend,
6864 .resume = ipw2100_resume,
6865#endif
6866};
6867
6868
6869/**
6870 * Initialize the ipw2100 driver/module
6871 *
6872 * @returns 0 if ok, < 0 errno node con error.
6873 *
6874 * Note: we cannot init the /proc stuff until the PCI driver is there,
6875 * or we risk an unlikely race condition on someone accessing
6876 * uninitialized data in the PCI dev struct through /proc.
6877 */
6878static int __init ipw2100_init(void)
6879{
6880 int ret;
6881
6882 printk(KERN_INFO DRV_NAME ": %s, %s\n", DRV_DESCRIPTION, DRV_VERSION);
6883 printk(KERN_INFO DRV_NAME ": %s\n", DRV_COPYRIGHT);
6884
6885#ifdef CONFIG_IEEE80211_NOWEP
6886 IPW_DEBUG_INFO(DRV_NAME ": Compiled with WEP disabled.\n");
6887#endif
6888
6889 ret = pci_module_init(&ipw2100_pci_driver);
6890
6891#ifdef CONFIG_IPW_DEBUG
6892 ipw2100_debug_level = debug;
6893 driver_create_file(&ipw2100_pci_driver.driver,
6894 &driver_attr_debug_level);
6895#endif
6896
6897 return ret;
6898}
6899
6900
6901/**
6902 * Cleanup ipw2100 driver registration
6903 */
6904static void __exit ipw2100_exit(void)
6905{
6906 /* FIXME: IPG: check that we have no instances of the devices open */
6907#ifdef CONFIG_IPW_DEBUG
6908 driver_remove_file(&ipw2100_pci_driver.driver,
6909 &driver_attr_debug_level);
6910#endif
6911 pci_unregister_driver(&ipw2100_pci_driver);
6912}
6913
6914module_init(ipw2100_init);
6915module_exit(ipw2100_exit);
6916
6917#define WEXT_USECHANNELS 1
6918
6919static const long ipw2100_frequencies[] = {
6920 2412, 2417, 2422, 2427,
6921 2432, 2437, 2442, 2447,
6922 2452, 2457, 2462, 2467,
6923 2472, 2484
6924};
6925
6926#define FREQ_COUNT (sizeof(ipw2100_frequencies) / \
6927 sizeof(ipw2100_frequencies[0]))
6928
6929static const long ipw2100_rates_11b[] = {
6930 1000000,
6931 2000000,
6932 5500000,
6933 11000000
6934};
6935
6936#define RATE_COUNT (sizeof(ipw2100_rates_11b) / sizeof(ipw2100_rates_11b[0]))
6937
6938static int ipw2100_wx_get_name(struct net_device *dev,
6939 struct iw_request_info *info,
6940 union iwreq_data *wrqu, char *extra)
6941{
6942 /*
6943 * This can be called at any time. No action lock required
6944 */
6945
6946 struct ipw2100_priv *priv = ieee80211_priv(dev);
6947 if (!(priv->status & STATUS_ASSOCIATED))
6948 strcpy(wrqu->name, "unassociated");
6949 else
6950 snprintf(wrqu->name, IFNAMSIZ, "IEEE 802.11b");
6951
6952 IPW_DEBUG_WX("Name: %s\n", wrqu->name);
6953 return 0;
6954}
6955
6956
6957static int ipw2100_wx_set_freq(struct net_device *dev,
6958 struct iw_request_info *info,
6959 union iwreq_data *wrqu, char *extra)
6960{
6961 struct ipw2100_priv *priv = ieee80211_priv(dev);
6962 struct iw_freq *fwrq = &wrqu->freq;
6963 int err = 0;
6964
6965 if (priv->ieee->iw_mode == IW_MODE_INFRA)
6966 return -EOPNOTSUPP;
6967
6968 down(&priv->action_sem);
6969 if (!(priv->status & STATUS_INITIALIZED)) {
6970 err = -EIO;
6971 goto done;
6972 }
6973
6974 /* if setting by freq convert to channel */
6975 if (fwrq->e == 1) {
6976 if ((fwrq->m >= (int) 2.412e8 &&
6977 fwrq->m <= (int) 2.487e8)) {
6978 int f = fwrq->m / 100000;
6979 int c = 0;
6980
6981 while ((c < REG_MAX_CHANNEL) &&
6982 (f != ipw2100_frequencies[c]))
6983 c++;
6984
6985 /* hack to fall through */
6986 fwrq->e = 0;
6987 fwrq->m = c + 1;
6988 }
6989 }
6990
6991 if (fwrq->e > 0 || fwrq->m > 1000)
6992 return -EOPNOTSUPP;
6993 else { /* Set the channel */
6994 IPW_DEBUG_WX("SET Freq/Channel -> %d \n", fwrq->m);
6995 err = ipw2100_set_channel(priv, fwrq->m, 0);
6996 }
6997
6998 done:
6999 up(&priv->action_sem);
7000 return err;
7001}
7002
7003
7004static int ipw2100_wx_get_freq(struct net_device *dev,
7005 struct iw_request_info *info,
7006 union iwreq_data *wrqu, char *extra)
7007{
7008 /*
7009 * This can be called at any time. No action lock required
7010 */
7011
7012 struct ipw2100_priv *priv = ieee80211_priv(dev);
7013
7014 wrqu->freq.e = 0;
7015
7016 /* If we are associated, trying to associate, or have a statically
7017 * configured CHANNEL then return that; otherwise return ANY */
7018 if (priv->config & CFG_STATIC_CHANNEL ||
7019 priv->status & STATUS_ASSOCIATED)
7020 wrqu->freq.m = priv->channel;
7021 else
7022 wrqu->freq.m = 0;
7023
7024 IPW_DEBUG_WX("GET Freq/Channel -> %d \n", priv->channel);
7025 return 0;
7026
7027}
7028
7029static int ipw2100_wx_set_mode(struct net_device *dev,
7030 struct iw_request_info *info,
7031 union iwreq_data *wrqu, char *extra)
7032{
7033 struct ipw2100_priv *priv = ieee80211_priv(dev);
7034 int err = 0;
7035
7036 IPW_DEBUG_WX("SET Mode -> %d \n", wrqu->mode);
7037
7038 if (wrqu->mode == priv->ieee->iw_mode)
7039 return 0;
7040
7041 down(&priv->action_sem);
7042 if (!(priv->status & STATUS_INITIALIZED)) {
7043 err = -EIO;
7044 goto done;
7045 }
7046
7047 switch (wrqu->mode) {
7048#ifdef CONFIG_IPW2100_MONITOR
7049 case IW_MODE_MONITOR:
7050 err = ipw2100_switch_mode(priv, IW_MODE_MONITOR);
7051 break;
7052#endif /* CONFIG_IPW2100_MONITOR */
7053 case IW_MODE_ADHOC:
7054 err = ipw2100_switch_mode(priv, IW_MODE_ADHOC);
7055 break;
7056 case IW_MODE_INFRA:
7057 case IW_MODE_AUTO:
7058 default:
7059 err = ipw2100_switch_mode(priv, IW_MODE_INFRA);
7060 break;
7061 }
7062
7063done:
7064 up(&priv->action_sem);
7065 return err;
7066}
7067
7068static int ipw2100_wx_get_mode(struct net_device *dev,
7069 struct iw_request_info *info,
7070 union iwreq_data *wrqu, char *extra)
7071{
7072 /*
7073 * This can be called at any time. No action lock required
7074 */
7075
7076 struct ipw2100_priv *priv = ieee80211_priv(dev);
7077
7078 wrqu->mode = priv->ieee->iw_mode;
7079 IPW_DEBUG_WX("GET Mode -> %d\n", wrqu->mode);
7080
7081 return 0;
7082}
7083
7084
7085#define POWER_MODES 5
7086
7087/* Values are in microsecond */
7088static const s32 timeout_duration[POWER_MODES] = {
7089 350000,
7090 250000,
7091 75000,
7092 37000,
7093 25000,
7094};
7095
7096static const s32 period_duration[POWER_MODES] = {
7097 400000,
7098 700000,
7099 1000000,
7100 1000000,
7101 1000000
7102};
7103
7104static int ipw2100_wx_get_range(struct net_device *dev,
7105 struct iw_request_info *info,
7106 union iwreq_data *wrqu, char *extra)
7107{
7108 /*
7109 * This can be called at any time. No action lock required
7110 */
7111
7112 struct ipw2100_priv *priv = ieee80211_priv(dev);
7113 struct iw_range *range = (struct iw_range *)extra;
7114 u16 val;
7115 int i, level;
7116
7117 wrqu->data.length = sizeof(*range);
7118 memset(range, 0, sizeof(*range));
7119
7120 /* Let's try to keep this struct in the same order as in
7121 * linux/include/wireless.h
7122 */
7123
7124 /* TODO: See what values we can set, and remove the ones we can't
7125 * set, or fill them with some default data.
7126 */
7127
7128 /* ~5 Mb/s real (802.11b) */
7129 range->throughput = 5 * 1000 * 1000;
7130
7131// range->sensitivity; /* signal level threshold range */
7132
7133 range->max_qual.qual = 100;
7134 /* TODO: Find real max RSSI and stick here */
7135 range->max_qual.level = 0;
7136 range->max_qual.noise = 0;
7137 range->max_qual.updated = 7; /* Updated all three */
7138
7139 range->avg_qual.qual = 70; /* > 8% missed beacons is 'bad' */
7140 /* TODO: Find real 'good' to 'bad' threshol value for RSSI */
7141 range->avg_qual.level = 20 + IPW2100_RSSI_TO_DBM;
7142 range->avg_qual.noise = 0;
7143 range->avg_qual.updated = 7; /* Updated all three */
7144
7145 range->num_bitrates = RATE_COUNT;
7146
7147 for (i = 0; i < RATE_COUNT && i < IW_MAX_BITRATES; i++) {
7148 range->bitrate[i] = ipw2100_rates_11b[i];
7149 }
7150
7151 range->min_rts = MIN_RTS_THRESHOLD;
7152 range->max_rts = MAX_RTS_THRESHOLD;
7153 range->min_frag = MIN_FRAG_THRESHOLD;
7154 range->max_frag = MAX_FRAG_THRESHOLD;
7155
7156 range->min_pmp = period_duration[0]; /* Minimal PM period */
7157 range->max_pmp = period_duration[POWER_MODES-1];/* Maximal PM period */
7158 range->min_pmt = timeout_duration[POWER_MODES-1]; /* Minimal PM timeout */
7159 range->max_pmt = timeout_duration[0];/* Maximal PM timeout */
7160
7161 /* How to decode max/min PM period */
7162 range->pmp_flags = IW_POWER_PERIOD;
7163 /* How to decode max/min PM period */
7164 range->pmt_flags = IW_POWER_TIMEOUT;
7165 /* What PM options are supported */
7166 range->pm_capa = IW_POWER_TIMEOUT | IW_POWER_PERIOD;
7167
7168 range->encoding_size[0] = 5;
7169 range->encoding_size[1] = 13; /* Different token sizes */
7170 range->num_encoding_sizes = 2; /* Number of entry in the list */
7171 range->max_encoding_tokens = WEP_KEYS; /* Max number of tokens */
7172// range->encoding_login_index; /* token index for login token */
7173
7174 if (priv->ieee->iw_mode == IW_MODE_ADHOC) {
7175 range->txpower_capa = IW_TXPOW_DBM;
7176 range->num_txpower = IW_MAX_TXPOWER;
7177 for (i = 0, level = (IPW_TX_POWER_MAX_DBM * 16); i < IW_MAX_TXPOWER;
7178 i++, level -= ((IPW_TX_POWER_MAX_DBM - IPW_TX_POWER_MIN_DBM) * 16) /
7179 (IW_MAX_TXPOWER - 1))
7180 range->txpower[i] = level / 16;
7181 } else {
7182 range->txpower_capa = 0;
7183 range->num_txpower = 0;
7184 }
7185
7186
7187 /* Set the Wireless Extension versions */
7188 range->we_version_compiled = WIRELESS_EXT;
7189 range->we_version_source = 16;
7190
7191// range->retry_capa; /* What retry options are supported */
7192// range->retry_flags; /* How to decode max/min retry limit */
7193// range->r_time_flags; /* How to decode max/min retry life */
7194// range->min_retry; /* Minimal number of retries */
7195// range->max_retry; /* Maximal number of retries */
7196// range->min_r_time; /* Minimal retry lifetime */
7197// range->max_r_time; /* Maximal retry lifetime */
7198
7199 range->num_channels = FREQ_COUNT;
7200
7201 val = 0;
7202 for (i = 0; i < FREQ_COUNT; i++) {
7203 // TODO: Include only legal frequencies for some countries
7204// if (local->channel_mask & (1 << i)) {
7205 range->freq[val].i = i + 1;
7206 range->freq[val].m = ipw2100_frequencies[i] * 100000;
7207 range->freq[val].e = 1;
7208 val++;
7209// }
7210 if (val == IW_MAX_FREQUENCIES)
7211 break;
7212 }
7213 range->num_frequency = val;
7214
7215 IPW_DEBUG_WX("GET Range\n");
7216
7217 return 0;
7218}
7219
7220static int ipw2100_wx_set_wap(struct net_device *dev,
7221 struct iw_request_info *info,
7222 union iwreq_data *wrqu, char *extra)
7223{
7224 struct ipw2100_priv *priv = ieee80211_priv(dev);
7225 int err = 0;
7226
7227 static const unsigned char any[] = {
7228 0xff, 0xff, 0xff, 0xff, 0xff, 0xff
7229 };
7230 static const unsigned char off[] = {
7231 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
7232 };
7233
7234 // sanity checks
7235 if (wrqu->ap_addr.sa_family != ARPHRD_ETHER)
7236 return -EINVAL;
7237
7238 down(&priv->action_sem);
7239 if (!(priv->status & STATUS_INITIALIZED)) {
7240 err = -EIO;
7241 goto done;
7242 }
7243
7244 if (!memcmp(any, wrqu->ap_addr.sa_data, ETH_ALEN) ||
7245 !memcmp(off, wrqu->ap_addr.sa_data, ETH_ALEN)) {
7246 /* we disable mandatory BSSID association */
7247 IPW_DEBUG_WX("exit - disable mandatory BSSID\n");
7248 priv->config &= ~CFG_STATIC_BSSID;
7249 err = ipw2100_set_mandatory_bssid(priv, NULL, 0);
7250 goto done;
7251 }
7252
7253 priv->config |= CFG_STATIC_BSSID;
7254 memcpy(priv->mandatory_bssid_mac, wrqu->ap_addr.sa_data, ETH_ALEN);
7255
7256 err = ipw2100_set_mandatory_bssid(priv, wrqu->ap_addr.sa_data, 0);
7257
7258 IPW_DEBUG_WX("SET BSSID -> %02X:%02X:%02X:%02X:%02X:%02X\n",
7259 wrqu->ap_addr.sa_data[0] & 0xff,
7260 wrqu->ap_addr.sa_data[1] & 0xff,
7261 wrqu->ap_addr.sa_data[2] & 0xff,
7262 wrqu->ap_addr.sa_data[3] & 0xff,
7263 wrqu->ap_addr.sa_data[4] & 0xff,
7264 wrqu->ap_addr.sa_data[5] & 0xff);
7265
7266 done:
7267 up(&priv->action_sem);
7268 return err;
7269}
7270
7271static int ipw2100_wx_get_wap(struct net_device *dev,
7272 struct iw_request_info *info,
7273 union iwreq_data *wrqu, char *extra)
7274{
7275 /*
7276 * This can be called at any time. No action lock required
7277 */
7278
7279 struct ipw2100_priv *priv = ieee80211_priv(dev);
7280
7281 /* If we are associated, trying to associate, or have a statically
7282 * configured BSSID then return that; otherwise return ANY */
7283 if (priv->config & CFG_STATIC_BSSID ||
7284 priv->status & STATUS_ASSOCIATED) {
7285 wrqu->ap_addr.sa_family = ARPHRD_ETHER;
7286 memcpy(wrqu->ap_addr.sa_data, &priv->bssid, ETH_ALEN);
7287 } else
7288 memset(wrqu->ap_addr.sa_data, 0, ETH_ALEN);
7289
7290 IPW_DEBUG_WX("Getting WAP BSSID: " MAC_FMT "\n",
7291 MAC_ARG(wrqu->ap_addr.sa_data));
7292 return 0;
7293}
7294
7295static int ipw2100_wx_set_essid(struct net_device *dev,
7296 struct iw_request_info *info,
7297 union iwreq_data *wrqu, char *extra)
7298{
7299 struct ipw2100_priv *priv = ieee80211_priv(dev);
7300 char *essid = ""; /* ANY */
7301 int length = 0;
7302 int err = 0;
7303
7304 down(&priv->action_sem);
7305 if (!(priv->status & STATUS_INITIALIZED)) {
7306 err = -EIO;
7307 goto done;
7308 }
7309
7310 if (wrqu->essid.flags && wrqu->essid.length) {
7311 length = wrqu->essid.length - 1;
7312 essid = extra;
7313 }
7314
7315 if (length == 0) {
7316 IPW_DEBUG_WX("Setting ESSID to ANY\n");
7317 priv->config &= ~CFG_STATIC_ESSID;
7318 err = ipw2100_set_essid(priv, NULL, 0, 0);
7319 goto done;
7320 }
7321
7322 length = min(length, IW_ESSID_MAX_SIZE);
7323
7324 priv->config |= CFG_STATIC_ESSID;
7325
7326 if (priv->essid_len == length && !memcmp(priv->essid, extra, length)) {
7327 IPW_DEBUG_WX("ESSID set to current ESSID.\n");
7328 err = 0;
7329 goto done;
7330 }
7331
7332 IPW_DEBUG_WX("Setting ESSID: '%s' (%d)\n", escape_essid(essid, length),
7333 length);
7334
7335 priv->essid_len = length;
7336 memcpy(priv->essid, essid, priv->essid_len);
7337
7338 err = ipw2100_set_essid(priv, essid, length, 0);
7339
7340 done:
7341 up(&priv->action_sem);
7342 return err;
7343}
7344
7345static int ipw2100_wx_get_essid(struct net_device *dev,
7346 struct iw_request_info *info,
7347 union iwreq_data *wrqu, char *extra)
7348{
7349 /*
7350 * This can be called at any time. No action lock required
7351 */
7352
7353 struct ipw2100_priv *priv = ieee80211_priv(dev);
7354
7355 /* If we are associated, trying to associate, or have a statically
7356 * configured ESSID then return that; otherwise return ANY */
7357 if (priv->config & CFG_STATIC_ESSID ||
7358 priv->status & STATUS_ASSOCIATED) {
7359 IPW_DEBUG_WX("Getting essid: '%s'\n",
7360 escape_essid(priv->essid, priv->essid_len));
7361 memcpy(extra, priv->essid, priv->essid_len);
7362 wrqu->essid.length = priv->essid_len;
7363 wrqu->essid.flags = 1; /* active */
7364 } else {
7365 IPW_DEBUG_WX("Getting essid: ANY\n");
7366 wrqu->essid.length = 0;
7367 wrqu->essid.flags = 0; /* active */
7368 }
7369
7370 return 0;
7371}
7372
7373static int ipw2100_wx_set_nick(struct net_device *dev,
7374 struct iw_request_info *info,
7375 union iwreq_data *wrqu, char *extra)
7376{
7377 /*
7378 * This can be called at any time. No action lock required
7379 */
7380
7381 struct ipw2100_priv *priv = ieee80211_priv(dev);
7382
7383 if (wrqu->data.length > IW_ESSID_MAX_SIZE)
7384 return -E2BIG;
7385
7386 wrqu->data.length = min((size_t)wrqu->data.length, sizeof(priv->nick));
7387 memset(priv->nick, 0, sizeof(priv->nick));
7388 memcpy(priv->nick, extra, wrqu->data.length);
7389
7390 IPW_DEBUG_WX("SET Nickname -> %s \n", priv->nick);
7391
7392 return 0;
7393}
7394
7395static int ipw2100_wx_get_nick(struct net_device *dev,
7396 struct iw_request_info *info,
7397 union iwreq_data *wrqu, char *extra)
7398{
7399 /*
7400 * This can be called at any time. No action lock required
7401 */
7402
7403 struct ipw2100_priv *priv = ieee80211_priv(dev);
7404
7405 wrqu->data.length = strlen(priv->nick) + 1;
7406 memcpy(extra, priv->nick, wrqu->data.length);
7407 wrqu->data.flags = 1; /* active */
7408
7409 IPW_DEBUG_WX("GET Nickname -> %s \n", extra);
7410
7411 return 0;
7412}
7413
7414static int ipw2100_wx_set_rate(struct net_device *dev,
7415 struct iw_request_info *info,
7416 union iwreq_data *wrqu, char *extra)
7417{
7418 struct ipw2100_priv *priv = ieee80211_priv(dev);
7419 u32 target_rate = wrqu->bitrate.value;
7420 u32 rate;
7421 int err = 0;
7422
7423 down(&priv->action_sem);
7424 if (!(priv->status & STATUS_INITIALIZED)) {
7425 err = -EIO;
7426 goto done;
7427 }
7428
7429 rate = 0;
7430
7431 if (target_rate == 1000000 ||
7432 (!wrqu->bitrate.fixed && target_rate > 1000000))
7433 rate |= TX_RATE_1_MBIT;
7434 if (target_rate == 2000000 ||
7435 (!wrqu->bitrate.fixed && target_rate > 2000000))
7436 rate |= TX_RATE_2_MBIT;
7437 if (target_rate == 5500000 ||
7438 (!wrqu->bitrate.fixed && target_rate > 5500000))
7439 rate |= TX_RATE_5_5_MBIT;
7440 if (target_rate == 11000000 ||
7441 (!wrqu->bitrate.fixed && target_rate > 11000000))
7442 rate |= TX_RATE_11_MBIT;
7443 if (rate == 0)
7444 rate = DEFAULT_TX_RATES;
7445
7446 err = ipw2100_set_tx_rates(priv, rate, 0);
7447
7448 IPW_DEBUG_WX("SET Rate -> %04X \n", rate);
7449 done:
7450 up(&priv->action_sem);
7451 return err;
7452}
7453
7454
7455static int ipw2100_wx_get_rate(struct net_device *dev,
7456 struct iw_request_info *info,
7457 union iwreq_data *wrqu, char *extra)
7458{
7459 struct ipw2100_priv *priv = ieee80211_priv(dev);
7460 int val;
7461 int len = sizeof(val);
7462 int err = 0;
7463
7464 if (!(priv->status & STATUS_ENABLED) ||
7465 priv->status & STATUS_RF_KILL_MASK ||
7466 !(priv->status & STATUS_ASSOCIATED)) {
7467 wrqu->bitrate.value = 0;
7468 return 0;
7469 }
7470
7471 down(&priv->action_sem);
7472 if (!(priv->status & STATUS_INITIALIZED)) {
7473 err = -EIO;
7474 goto done;
7475 }
7476
7477 err = ipw2100_get_ordinal(priv, IPW_ORD_CURRENT_TX_RATE, &val, &len);
7478 if (err) {
7479 IPW_DEBUG_WX("failed querying ordinals.\n");
7480 return err;
7481 }
7482
7483 switch (val & TX_RATE_MASK) {
7484 case TX_RATE_1_MBIT:
7485 wrqu->bitrate.value = 1000000;
7486 break;
7487 case TX_RATE_2_MBIT:
7488 wrqu->bitrate.value = 2000000;
7489 break;
7490 case TX_RATE_5_5_MBIT:
7491 wrqu->bitrate.value = 5500000;
7492 break;
7493 case TX_RATE_11_MBIT:
7494 wrqu->bitrate.value = 11000000;
7495 break;
7496 default:
7497 wrqu->bitrate.value = 0;
7498 }
7499
7500 IPW_DEBUG_WX("GET Rate -> %d \n", wrqu->bitrate.value);
7501
7502 done:
7503 up(&priv->action_sem);
7504 return err;
7505}
7506
7507static int ipw2100_wx_set_rts(struct net_device *dev,
7508 struct iw_request_info *info,
7509 union iwreq_data *wrqu, char *extra)
7510{
7511 struct ipw2100_priv *priv = ieee80211_priv(dev);
7512 int value, err;
7513
7514 /* Auto RTS not yet supported */
7515 if (wrqu->rts.fixed == 0)
7516 return -EINVAL;
7517
7518 down(&priv->action_sem);
7519 if (!(priv->status & STATUS_INITIALIZED)) {
7520 err = -EIO;
7521 goto done;
7522 }
7523
7524 if (wrqu->rts.disabled)
7525 value = priv->rts_threshold | RTS_DISABLED;
7526 else {
7527 if (wrqu->rts.value < 1 ||
7528 wrqu->rts.value > 2304) {
7529 err = -EINVAL;
7530 goto done;
7531 }
7532 value = wrqu->rts.value;
7533 }
7534
7535 err = ipw2100_set_rts_threshold(priv, value);
7536
7537 IPW_DEBUG_WX("SET RTS Threshold -> 0x%08X \n", value);
7538 done:
7539 up(&priv->action_sem);
7540 return err;
7541}
7542
7543static int ipw2100_wx_get_rts(struct net_device *dev,
7544 struct iw_request_info *info,
7545 union iwreq_data *wrqu, char *extra)
7546{
7547 /*
7548 * This can be called at any time. No action lock required
7549 */
7550
7551 struct ipw2100_priv *priv = ieee80211_priv(dev);
7552
7553 wrqu->rts.value = priv->rts_threshold & ~RTS_DISABLED;
7554 wrqu->rts.fixed = 1; /* no auto select */
7555
7556 /* If RTS is set to the default value, then it is disabled */
7557 wrqu->rts.disabled = (priv->rts_threshold & RTS_DISABLED) ? 1 : 0;
7558
7559 IPW_DEBUG_WX("GET RTS Threshold -> 0x%08X \n", wrqu->rts.value);
7560
7561 return 0;
7562}
7563
7564static int ipw2100_wx_set_txpow(struct net_device *dev,
7565 struct iw_request_info *info,
7566 union iwreq_data *wrqu, char *extra)
7567{
7568 struct ipw2100_priv *priv = ieee80211_priv(dev);
7569 int err = 0, value;
7570
7571 if (priv->ieee->iw_mode != IW_MODE_ADHOC)
7572 return -EINVAL;
7573
7574 if (wrqu->txpower.disabled == 1 || wrqu->txpower.fixed == 0)
7575 value = IPW_TX_POWER_DEFAULT;
7576 else {
7577 if (wrqu->txpower.value < IPW_TX_POWER_MIN_DBM ||
7578 wrqu->txpower.value > IPW_TX_POWER_MAX_DBM)
7579 return -EINVAL;
7580
7581 value = (wrqu->txpower.value - IPW_TX_POWER_MIN_DBM) * 16 /
7582 (IPW_TX_POWER_MAX_DBM - IPW_TX_POWER_MIN_DBM);
7583 }
7584
7585 down(&priv->action_sem);
7586 if (!(priv->status & STATUS_INITIALIZED)) {
7587 err = -EIO;
7588 goto done;
7589 }
7590
7591 err = ipw2100_set_tx_power(priv, value);
7592
7593 IPW_DEBUG_WX("SET TX Power -> %d \n", value);
7594
7595 done:
7596 up(&priv->action_sem);
7597 return err;
7598}
7599
7600static int ipw2100_wx_get_txpow(struct net_device *dev,
7601 struct iw_request_info *info,
7602 union iwreq_data *wrqu, char *extra)
7603{
7604 /*
7605 * This can be called at any time. No action lock required
7606 */
7607
7608 struct ipw2100_priv *priv = ieee80211_priv(dev);
7609
7610 if (priv->ieee->iw_mode != IW_MODE_ADHOC) {
7611 wrqu->power.disabled = 1;
7612 return 0;
7613 }
7614
7615 if (priv->tx_power == IPW_TX_POWER_DEFAULT) {
7616 wrqu->power.fixed = 0;
7617 wrqu->power.value = IPW_TX_POWER_MAX_DBM;
7618 wrqu->power.disabled = 1;
7619 } else {
7620 wrqu->power.disabled = 0;
7621 wrqu->power.fixed = 1;
7622 wrqu->power.value =
7623 (priv->tx_power *
7624 (IPW_TX_POWER_MAX_DBM - IPW_TX_POWER_MIN_DBM)) /
7625 (IPW_TX_POWER_MAX - IPW_TX_POWER_MIN) +
7626 IPW_TX_POWER_MIN_DBM;
7627 }
7628
7629 wrqu->power.flags = IW_TXPOW_DBM;
7630
7631 IPW_DEBUG_WX("GET TX Power -> %d \n", wrqu->power.value);
7632
7633 return 0;
7634}
7635
7636static int ipw2100_wx_set_frag(struct net_device *dev,
7637 struct iw_request_info *info,
7638 union iwreq_data *wrqu, char *extra)
7639{
7640 /*
7641 * This can be called at any time. No action lock required
7642 */
7643
7644 struct ipw2100_priv *priv = ieee80211_priv(dev);
7645
7646 if (!wrqu->frag.fixed)
7647 return -EINVAL;
7648
7649 if (wrqu->frag.disabled) {
7650 priv->frag_threshold |= FRAG_DISABLED;
7651 priv->ieee->fts = DEFAULT_FTS;
7652 } else {
7653 if (wrqu->frag.value < MIN_FRAG_THRESHOLD ||
7654 wrqu->frag.value > MAX_FRAG_THRESHOLD)
7655 return -EINVAL;
7656
7657 priv->ieee->fts = wrqu->frag.value & ~0x1;
7658 priv->frag_threshold = priv->ieee->fts;
7659 }
7660
7661 IPW_DEBUG_WX("SET Frag Threshold -> %d \n", priv->ieee->fts);
7662
7663 return 0;
7664}
7665
7666static int ipw2100_wx_get_frag(struct net_device *dev,
7667 struct iw_request_info *info,
7668 union iwreq_data *wrqu, char *extra)
7669{
7670 /*
7671 * This can be called at any time. No action lock required
7672 */
7673
7674 struct ipw2100_priv *priv = ieee80211_priv(dev);
7675 wrqu->frag.value = priv->frag_threshold & ~FRAG_DISABLED;
7676 wrqu->frag.fixed = 0; /* no auto select */
7677 wrqu->frag.disabled = (priv->frag_threshold & FRAG_DISABLED) ? 1 : 0;
7678
7679 IPW_DEBUG_WX("GET Frag Threshold -> %d \n", wrqu->frag.value);
7680
7681 return 0;
7682}
7683
7684static int ipw2100_wx_set_retry(struct net_device *dev,
7685 struct iw_request_info *info,
7686 union iwreq_data *wrqu, char *extra)
7687{
7688 struct ipw2100_priv *priv = ieee80211_priv(dev);
7689 int err = 0;
7690
7691 if (wrqu->retry.flags & IW_RETRY_LIFETIME ||
7692 wrqu->retry.disabled)
7693 return -EINVAL;
7694
7695 if (!(wrqu->retry.flags & IW_RETRY_LIMIT))
7696 return 0;
7697
7698 down(&priv->action_sem);
7699 if (!(priv->status & STATUS_INITIALIZED)) {
7700 err = -EIO;
7701 goto done;
7702 }
7703
7704 if (wrqu->retry.flags & IW_RETRY_MIN) {
7705 err = ipw2100_set_short_retry(priv, wrqu->retry.value);
7706 IPW_DEBUG_WX("SET Short Retry Limit -> %d \n",
7707 wrqu->retry.value);
7708 goto done;
7709 }
7710
7711 if (wrqu->retry.flags & IW_RETRY_MAX) {
7712 err = ipw2100_set_long_retry(priv, wrqu->retry.value);
7713 IPW_DEBUG_WX("SET Long Retry Limit -> %d \n",
7714 wrqu->retry.value);
7715 goto done;
7716 }
7717
7718 err = ipw2100_set_short_retry(priv, wrqu->retry.value);
7719 if (!err)
7720 err = ipw2100_set_long_retry(priv, wrqu->retry.value);
7721
7722 IPW_DEBUG_WX("SET Both Retry Limits -> %d \n", wrqu->retry.value);
7723
7724 done:
7725 up(&priv->action_sem);
7726 return err;
7727}
7728
7729static int ipw2100_wx_get_retry(struct net_device *dev,
7730 struct iw_request_info *info,
7731 union iwreq_data *wrqu, char *extra)
7732{
7733 /*
7734 * This can be called at any time. No action lock required
7735 */
7736
7737 struct ipw2100_priv *priv = ieee80211_priv(dev);
7738
7739 wrqu->retry.disabled = 0; /* can't be disabled */
7740
7741 if ((wrqu->retry.flags & IW_RETRY_TYPE) ==
7742 IW_RETRY_LIFETIME)
7743 return -EINVAL;
7744
7745 if (wrqu->retry.flags & IW_RETRY_MAX) {
7746 wrqu->retry.flags = IW_RETRY_LIMIT & IW_RETRY_MAX;
7747 wrqu->retry.value = priv->long_retry_limit;
7748 } else {
7749 wrqu->retry.flags =
7750 (priv->short_retry_limit !=
7751 priv->long_retry_limit) ?
7752 IW_RETRY_LIMIT & IW_RETRY_MIN : IW_RETRY_LIMIT;
7753
7754 wrqu->retry.value = priv->short_retry_limit;
7755 }
7756
7757 IPW_DEBUG_WX("GET Retry -> %d \n", wrqu->retry.value);
7758
7759 return 0;
7760}
7761
7762static int ipw2100_wx_set_scan(struct net_device *dev,
7763 struct iw_request_info *info,
7764 union iwreq_data *wrqu, char *extra)
7765{
7766 struct ipw2100_priv *priv = ieee80211_priv(dev);
7767 int err = 0;
7768
7769 down(&priv->action_sem);
7770 if (!(priv->status & STATUS_INITIALIZED)) {
7771 err = -EIO;
7772 goto done;
7773 }
7774
7775 IPW_DEBUG_WX("Initiating scan...\n");
7776 if (ipw2100_set_scan_options(priv) ||
7777 ipw2100_start_scan(priv)) {
7778 IPW_DEBUG_WX("Start scan failed.\n");
7779
7780 /* TODO: Mark a scan as pending so when hardware initialized
7781 * a scan starts */
7782 }
7783
7784 done:
7785 up(&priv->action_sem);
7786 return err;
7787}
7788
7789static int ipw2100_wx_get_scan(struct net_device *dev,
7790 struct iw_request_info *info,
7791 union iwreq_data *wrqu, char *extra)
7792{
7793 /*
7794 * This can be called at any time. No action lock required
7795 */
7796
7797 struct ipw2100_priv *priv = ieee80211_priv(dev);
7798 return ieee80211_wx_get_scan(priv->ieee, info, wrqu, extra);
7799}
7800
7801
7802/*
7803 * Implementation based on code in hostap-driver v0.1.3 hostap_ioctl.c
7804 */
7805static int ipw2100_wx_set_encode(struct net_device *dev,
7806 struct iw_request_info *info,
7807 union iwreq_data *wrqu, char *key)
7808{
7809 /*
7810 * No check of STATUS_INITIALIZED required
7811 */
7812
7813 struct ipw2100_priv *priv = ieee80211_priv(dev);
7814 return ieee80211_wx_set_encode(priv->ieee, info, wrqu, key);
7815}
7816
7817static int ipw2100_wx_get_encode(struct net_device *dev,
7818 struct iw_request_info *info,
7819 union iwreq_data *wrqu, char *key)
7820{
7821 /*
7822 * This can be called at any time. No action lock required
7823 */
7824
7825 struct ipw2100_priv *priv = ieee80211_priv(dev);
7826 return ieee80211_wx_get_encode(priv->ieee, info, wrqu, key);
7827}
7828
7829static int ipw2100_wx_set_power(struct net_device *dev,
7830 struct iw_request_info *info,
7831 union iwreq_data *wrqu, char *extra)
7832{
7833 struct ipw2100_priv *priv = ieee80211_priv(dev);
7834 int err = 0;
7835
7836 down(&priv->action_sem);
7837 if (!(priv->status & STATUS_INITIALIZED)) {
7838 err = -EIO;
7839 goto done;
7840 }
7841
7842 if (wrqu->power.disabled) {
7843 priv->power_mode = IPW_POWER_LEVEL(priv->power_mode);
7844 err = ipw2100_set_power_mode(priv, IPW_POWER_MODE_CAM);
7845 IPW_DEBUG_WX("SET Power Management Mode -> off\n");
7846 goto done;
7847 }
7848
7849 switch (wrqu->power.flags & IW_POWER_MODE) {
7850 case IW_POWER_ON: /* If not specified */
7851 case IW_POWER_MODE: /* If set all mask */
7852 case IW_POWER_ALL_R: /* If explicitely state all */
7853 break;
7854 default: /* Otherwise we don't support it */
7855 IPW_DEBUG_WX("SET PM Mode: %X not supported.\n",
7856 wrqu->power.flags);
7857 err = -EOPNOTSUPP;
7858 goto done;
7859 }
7860
7861 /* If the user hasn't specified a power management mode yet, default
7862 * to BATTERY */
7863 priv->power_mode = IPW_POWER_ENABLED | priv->power_mode;
7864 err = ipw2100_set_power_mode(priv, IPW_POWER_LEVEL(priv->power_mode));
7865
7866 IPW_DEBUG_WX("SET Power Management Mode -> 0x%02X\n",
7867 priv->power_mode);
7868
7869 done:
7870 up(&priv->action_sem);
7871 return err;
7872
7873}
7874
7875static int ipw2100_wx_get_power(struct net_device *dev,
7876 struct iw_request_info *info,
7877 union iwreq_data *wrqu, char *extra)
7878{
7879 /*
7880 * This can be called at any time. No action lock required
7881 */
7882
7883 struct ipw2100_priv *priv = ieee80211_priv(dev);
7884
7885 if (!(priv->power_mode & IPW_POWER_ENABLED)) {
7886 wrqu->power.disabled = 1;
7887 } else {
7888 wrqu->power.disabled = 0;
7889 wrqu->power.flags = 0;
7890 }
7891
7892 IPW_DEBUG_WX("GET Power Management Mode -> %02X\n", priv->power_mode);
7893
7894 return 0;
7895}
7896
7897
7898/*
7899 *
7900 * IWPRIV handlers
7901 *
7902 */
7903#ifdef CONFIG_IPW2100_MONITOR
7904static int ipw2100_wx_set_promisc(struct net_device *dev,
7905 struct iw_request_info *info,
7906 union iwreq_data *wrqu, char *extra)
7907{
7908 struct ipw2100_priv *priv = ieee80211_priv(dev);
7909 int *parms = (int *)extra;
7910 int enable = (parms[0] > 0);
7911 int err = 0;
7912
7913 down(&priv->action_sem);
7914 if (!(priv->status & STATUS_INITIALIZED)) {
7915 err = -EIO;
7916 goto done;
7917 }
7918
7919 if (enable) {
7920 if (priv->ieee->iw_mode == IW_MODE_MONITOR) {
7921 err = ipw2100_set_channel(priv, parms[1], 0);
7922 goto done;
7923 }
7924 priv->channel = parms[1];
7925 err = ipw2100_switch_mode(priv, IW_MODE_MONITOR);
7926 } else {
7927 if (priv->ieee->iw_mode == IW_MODE_MONITOR)
7928 err = ipw2100_switch_mode(priv, priv->last_mode);
7929 }
7930 done:
7931 up(&priv->action_sem);
7932 return err;
7933}
7934
7935static int ipw2100_wx_reset(struct net_device *dev,
7936 struct iw_request_info *info,
7937 union iwreq_data *wrqu, char *extra)
7938{
7939 struct ipw2100_priv *priv = ieee80211_priv(dev);
7940 if (priv->status & STATUS_INITIALIZED)
7941 schedule_reset(priv);
7942 return 0;
7943}
7944
7945#endif
7946
7947static int ipw2100_wx_set_powermode(struct net_device *dev,
7948 struct iw_request_info *info,
7949 union iwreq_data *wrqu, char *extra)
7950{
7951 struct ipw2100_priv *priv = ieee80211_priv(dev);
7952 int err = 0, mode = *(int *)extra;
7953
7954 down(&priv->action_sem);
7955 if (!(priv->status & STATUS_INITIALIZED)) {
7956 err = -EIO;
7957 goto done;
7958 }
7959
7960 if ((mode < 1) || (mode > POWER_MODES))
7961 mode = IPW_POWER_AUTO;
7962
7963 if (priv->power_mode != mode)
7964 err = ipw2100_set_power_mode(priv, mode);
7965 done:
7966 up(&priv->action_sem);
7967 return err;
7968}
7969
7970#define MAX_POWER_STRING 80
7971static int ipw2100_wx_get_powermode(struct net_device *dev,
7972 struct iw_request_info *info,
7973 union iwreq_data *wrqu, char *extra)
7974{
7975 /*
7976 * This can be called at any time. No action lock required
7977 */
7978
7979 struct ipw2100_priv *priv = ieee80211_priv(dev);
7980 int level = IPW_POWER_LEVEL(priv->power_mode);
7981 s32 timeout, period;
7982
7983 if (!(priv->power_mode & IPW_POWER_ENABLED)) {
7984 snprintf(extra, MAX_POWER_STRING,
7985 "Power save level: %d (Off)", level);
7986 } else {
7987 switch (level) {
7988 case IPW_POWER_MODE_CAM:
7989 snprintf(extra, MAX_POWER_STRING,
7990 "Power save level: %d (None)", level);
7991 break;
7992 case IPW_POWER_AUTO:
7993 snprintf(extra, MAX_POWER_STRING,
7994 "Power save level: %d (Auto)", 0);
7995 break;
7996 default:
7997 timeout = timeout_duration[level - 1] / 1000;
7998 period = period_duration[level - 1] / 1000;
7999 snprintf(extra, MAX_POWER_STRING,
8000 "Power save level: %d "
8001 "(Timeout %dms, Period %dms)",
8002 level, timeout, period);
8003 }
8004 }
8005
8006 wrqu->data.length = strlen(extra) + 1;
8007
8008 return 0;
8009}
8010
8011
8012static int ipw2100_wx_set_preamble(struct net_device *dev,
8013 struct iw_request_info *info,
8014 union iwreq_data *wrqu, char *extra)
8015{
8016 struct ipw2100_priv *priv = ieee80211_priv(dev);
8017 int err, mode = *(int *)extra;
8018
8019 down(&priv->action_sem);
8020 if (!(priv->status & STATUS_INITIALIZED)) {
8021 err = -EIO;
8022 goto done;
8023 }
8024
8025 if (mode == 1)
8026 priv->config |= CFG_LONG_PREAMBLE;
8027 else if (mode == 0)
8028 priv->config &= ~CFG_LONG_PREAMBLE;
8029 else {
8030 err = -EINVAL;
8031 goto done;
8032 }
8033
8034 err = ipw2100_system_config(priv, 0);
8035
8036done:
8037 up(&priv->action_sem);
8038 return err;
8039}
8040
8041static int ipw2100_wx_get_preamble(struct net_device *dev,
8042 struct iw_request_info *info,
8043 union iwreq_data *wrqu, char *extra)
8044{
8045 /*
8046 * This can be called at any time. No action lock required
8047 */
8048
8049 struct ipw2100_priv *priv = ieee80211_priv(dev);
8050
8051 if (priv->config & CFG_LONG_PREAMBLE)
8052 snprintf(wrqu->name, IFNAMSIZ, "long (1)");
8053 else
8054 snprintf(wrqu->name, IFNAMSIZ, "auto (0)");
8055
8056 return 0;
8057}
8058
8059static iw_handler ipw2100_wx_handlers[] =
8060{
8061 NULL, /* SIOCSIWCOMMIT */
8062 ipw2100_wx_get_name, /* SIOCGIWNAME */
8063 NULL, /* SIOCSIWNWID */
8064 NULL, /* SIOCGIWNWID */
8065 ipw2100_wx_set_freq, /* SIOCSIWFREQ */
8066 ipw2100_wx_get_freq, /* SIOCGIWFREQ */
8067 ipw2100_wx_set_mode, /* SIOCSIWMODE */
8068 ipw2100_wx_get_mode, /* SIOCGIWMODE */
8069 NULL, /* SIOCSIWSENS */
8070 NULL, /* SIOCGIWSENS */
8071 NULL, /* SIOCSIWRANGE */
8072 ipw2100_wx_get_range, /* SIOCGIWRANGE */
8073 NULL, /* SIOCSIWPRIV */
8074 NULL, /* SIOCGIWPRIV */
8075 NULL, /* SIOCSIWSTATS */
8076 NULL, /* SIOCGIWSTATS */
8077 NULL, /* SIOCSIWSPY */
8078 NULL, /* SIOCGIWSPY */
8079 NULL, /* SIOCGIWTHRSPY */
8080 NULL, /* SIOCWIWTHRSPY */
8081 ipw2100_wx_set_wap, /* SIOCSIWAP */
8082 ipw2100_wx_get_wap, /* SIOCGIWAP */
8083 NULL, /* -- hole -- */
8084 NULL, /* SIOCGIWAPLIST -- deprecated */
8085 ipw2100_wx_set_scan, /* SIOCSIWSCAN */
8086 ipw2100_wx_get_scan, /* SIOCGIWSCAN */
8087 ipw2100_wx_set_essid, /* SIOCSIWESSID */
8088 ipw2100_wx_get_essid, /* SIOCGIWESSID */
8089 ipw2100_wx_set_nick, /* SIOCSIWNICKN */
8090 ipw2100_wx_get_nick, /* SIOCGIWNICKN */
8091 NULL, /* -- hole -- */
8092 NULL, /* -- hole -- */
8093 ipw2100_wx_set_rate, /* SIOCSIWRATE */
8094 ipw2100_wx_get_rate, /* SIOCGIWRATE */
8095 ipw2100_wx_set_rts, /* SIOCSIWRTS */
8096 ipw2100_wx_get_rts, /* SIOCGIWRTS */
8097 ipw2100_wx_set_frag, /* SIOCSIWFRAG */
8098 ipw2100_wx_get_frag, /* SIOCGIWFRAG */
8099 ipw2100_wx_set_txpow, /* SIOCSIWTXPOW */
8100 ipw2100_wx_get_txpow, /* SIOCGIWTXPOW */
8101 ipw2100_wx_set_retry, /* SIOCSIWRETRY */
8102 ipw2100_wx_get_retry, /* SIOCGIWRETRY */
8103 ipw2100_wx_set_encode, /* SIOCSIWENCODE */
8104 ipw2100_wx_get_encode, /* SIOCGIWENCODE */
8105 ipw2100_wx_set_power, /* SIOCSIWPOWER */
8106 ipw2100_wx_get_power, /* SIOCGIWPOWER */
8107};
8108
8109#define IPW2100_PRIV_SET_MONITOR SIOCIWFIRSTPRIV
8110#define IPW2100_PRIV_RESET SIOCIWFIRSTPRIV+1
8111#define IPW2100_PRIV_SET_POWER SIOCIWFIRSTPRIV+2
8112#define IPW2100_PRIV_GET_POWER SIOCIWFIRSTPRIV+3
8113#define IPW2100_PRIV_SET_LONGPREAMBLE SIOCIWFIRSTPRIV+4
8114#define IPW2100_PRIV_GET_LONGPREAMBLE SIOCIWFIRSTPRIV+5
8115
8116static const struct iw_priv_args ipw2100_private_args[] = {
8117
8118#ifdef CONFIG_IPW2100_MONITOR
8119 {
8120 IPW2100_PRIV_SET_MONITOR,
8121 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 2, 0, "monitor"
8122 },
8123 {
8124 IPW2100_PRIV_RESET,
8125 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 0, 0, "reset"
8126 },
8127#endif /* CONFIG_IPW2100_MONITOR */
8128
8129 {
8130 IPW2100_PRIV_SET_POWER,
8131 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "set_power"
8132 },
8133 {
8134 IPW2100_PRIV_GET_POWER,
8135 0, IW_PRIV_TYPE_CHAR | IW_PRIV_SIZE_FIXED | MAX_POWER_STRING, "get_power"
8136 },
8137 {
8138 IPW2100_PRIV_SET_LONGPREAMBLE,
8139 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "set_preamble"
8140 },
8141 {
8142 IPW2100_PRIV_GET_LONGPREAMBLE,
8143 0, IW_PRIV_TYPE_CHAR | IW_PRIV_SIZE_FIXED | IFNAMSIZ, "get_preamble"
8144 },
8145};
8146
8147static iw_handler ipw2100_private_handler[] = {
8148#ifdef CONFIG_IPW2100_MONITOR
8149 ipw2100_wx_set_promisc,
8150 ipw2100_wx_reset,
8151#else /* CONFIG_IPW2100_MONITOR */
8152 NULL,
8153 NULL,
8154#endif /* CONFIG_IPW2100_MONITOR */
8155 ipw2100_wx_set_powermode,
8156 ipw2100_wx_get_powermode,
8157 ipw2100_wx_set_preamble,
8158 ipw2100_wx_get_preamble,
8159};
8160
8161static struct iw_handler_def ipw2100_wx_handler_def =
8162{
8163 .standard = ipw2100_wx_handlers,
8164 .num_standard = sizeof(ipw2100_wx_handlers) / sizeof(iw_handler),
8165 .num_private = sizeof(ipw2100_private_handler) / sizeof(iw_handler),
8166 .num_private_args = sizeof(ipw2100_private_args) /
8167 sizeof(struct iw_priv_args),
8168 .private = (iw_handler *)ipw2100_private_handler,
8169 .private_args = (struct iw_priv_args *)ipw2100_private_args,
8170};
8171
8172/*
8173 * Get wireless statistics.
8174 * Called by /proc/net/wireless
8175 * Also called by SIOCGIWSTATS
8176 */
8177static struct iw_statistics *ipw2100_wx_wireless_stats(struct net_device * dev)
8178{
8179 enum {
8180 POOR = 30,
8181 FAIR = 60,
8182 GOOD = 80,
8183 VERY_GOOD = 90,
8184 EXCELLENT = 95,
8185 PERFECT = 100
8186 };
8187 int rssi_qual;
8188 int tx_qual;
8189 int beacon_qual;
8190
8191 struct ipw2100_priv *priv = ieee80211_priv(dev);
8192 struct iw_statistics *wstats;
8193 u32 rssi, quality, tx_retries, missed_beacons, tx_failures;
8194 u32 ord_len = sizeof(u32);
8195
8196 if (!priv)
8197 return (struct iw_statistics *) NULL;
8198
8199 wstats = &priv->wstats;
8200
8201 /* if hw is disabled, then ipw2100_get_ordinal() can't be called.
8202 * ipw2100_wx_wireless_stats seems to be called before fw is
8203 * initialized. STATUS_ASSOCIATED will only be set if the hw is up
8204 * and associated; if not associcated, the values are all meaningless
8205 * anyway, so set them all to NULL and INVALID */
8206 if (!(priv->status & STATUS_ASSOCIATED)) {
8207 wstats->miss.beacon = 0;
8208 wstats->discard.retries = 0;
8209 wstats->qual.qual = 0;
8210 wstats->qual.level = 0;
8211 wstats->qual.noise = 0;
8212 wstats->qual.updated = 7;
8213 wstats->qual.updated |= IW_QUAL_NOISE_INVALID |
8214 IW_QUAL_QUAL_INVALID | IW_QUAL_LEVEL_INVALID;
8215 return wstats;
8216 }
8217
8218 if (ipw2100_get_ordinal(priv, IPW_ORD_STAT_PERCENT_MISSED_BCNS,
8219 &missed_beacons, &ord_len))
8220 goto fail_get_ordinal;
8221
8222 /* If we don't have a connection the quality and level is 0*/
8223 if (!(priv->status & STATUS_ASSOCIATED)) {
8224 wstats->qual.qual = 0;
8225 wstats->qual.level = 0;
8226 } else {
8227 if (ipw2100_get_ordinal(priv, IPW_ORD_RSSI_AVG_CURR,
8228 &rssi, &ord_len))
8229 goto fail_get_ordinal;
8230 wstats->qual.level = rssi + IPW2100_RSSI_TO_DBM;
8231 if (rssi < 10)
8232 rssi_qual = rssi * POOR / 10;
8233 else if (rssi < 15)
8234 rssi_qual = (rssi - 10) * (FAIR - POOR) / 5 + POOR;
8235 else if (rssi < 20)
8236 rssi_qual = (rssi - 15) * (GOOD - FAIR) / 5 + FAIR;
8237 else if (rssi < 30)
8238 rssi_qual = (rssi - 20) * (VERY_GOOD - GOOD) /
8239 10 + GOOD;
8240 else
8241 rssi_qual = (rssi - 30) * (PERFECT - VERY_GOOD) /
8242 10 + VERY_GOOD;
8243
8244 if (ipw2100_get_ordinal(priv, IPW_ORD_STAT_PERCENT_RETRIES,
8245 &tx_retries, &ord_len))
8246 goto fail_get_ordinal;
8247
8248 if (tx_retries > 75)
8249 tx_qual = (90 - tx_retries) * POOR / 15;
8250 else if (tx_retries > 70)
8251 tx_qual = (75 - tx_retries) * (FAIR - POOR) / 5 + POOR;
8252 else if (tx_retries > 65)
8253 tx_qual = (70 - tx_retries) * (GOOD - FAIR) / 5 + FAIR;
8254 else if (tx_retries > 50)
8255 tx_qual = (65 - tx_retries) * (VERY_GOOD - GOOD) /
8256 15 + GOOD;
8257 else
8258 tx_qual = (50 - tx_retries) *
8259 (PERFECT - VERY_GOOD) / 50 + VERY_GOOD;
8260
8261 if (missed_beacons > 50)
8262 beacon_qual = (60 - missed_beacons) * POOR / 10;
8263 else if (missed_beacons > 40)
8264 beacon_qual = (50 - missed_beacons) * (FAIR - POOR) /
8265 10 + POOR;
8266 else if (missed_beacons > 32)
8267 beacon_qual = (40 - missed_beacons) * (GOOD - FAIR) /
8268 18 + FAIR;
8269 else if (missed_beacons > 20)
8270 beacon_qual = (32 - missed_beacons) *
8271 (VERY_GOOD - GOOD) / 20 + GOOD;
8272 else
8273 beacon_qual = (20 - missed_beacons) *
8274 (PERFECT - VERY_GOOD) / 20 + VERY_GOOD;
8275
8276 quality = min(beacon_qual, min(tx_qual, rssi_qual));
8277
8278#ifdef CONFIG_IPW_DEBUG
8279 if (beacon_qual == quality)
8280 IPW_DEBUG_WX("Quality clamped by Missed Beacons\n");
8281 else if (tx_qual == quality)
8282 IPW_DEBUG_WX("Quality clamped by Tx Retries\n");
8283 else if (quality != 100)
8284 IPW_DEBUG_WX("Quality clamped by Signal Strength\n");
8285 else
8286 IPW_DEBUG_WX("Quality not clamped.\n");
8287#endif
8288
8289 wstats->qual.qual = quality;
8290 wstats->qual.level = rssi + IPW2100_RSSI_TO_DBM;
8291 }
8292
8293 wstats->qual.noise = 0;
8294 wstats->qual.updated = 7;
8295 wstats->qual.updated |= IW_QUAL_NOISE_INVALID;
8296
8297 /* FIXME: this is percent and not a # */
8298 wstats->miss.beacon = missed_beacons;
8299
8300 if (ipw2100_get_ordinal(priv, IPW_ORD_STAT_TX_FAILURES,
8301 &tx_failures, &ord_len))
8302 goto fail_get_ordinal;
8303 wstats->discard.retries = tx_failures;
8304
8305 return wstats;
8306
8307 fail_get_ordinal:
8308 IPW_DEBUG_WX("failed querying ordinals.\n");
8309
8310 return (struct iw_statistics *) NULL;
8311}
8312
8313static void ipw2100_wx_event_work(struct ipw2100_priv *priv)
8314{
8315 union iwreq_data wrqu;
8316 int len = ETH_ALEN;
8317
8318 if (priv->status & STATUS_STOPPING)
8319 return;
8320
8321 down(&priv->action_sem);
8322
8323 IPW_DEBUG_WX("enter\n");
8324
8325 up(&priv->action_sem);
8326
8327 wrqu.ap_addr.sa_family = ARPHRD_ETHER;
8328
8329 /* Fetch BSSID from the hardware */
8330 if (!(priv->status & (STATUS_ASSOCIATING | STATUS_ASSOCIATED)) ||
8331 priv->status & STATUS_RF_KILL_MASK ||
8332 ipw2100_get_ordinal(priv, IPW_ORD_STAT_ASSN_AP_BSSID,
8333 &priv->bssid, &len)) {
8334 memset(wrqu.ap_addr.sa_data, 0, ETH_ALEN);
8335 } else {
8336 /* We now have the BSSID, so can finish setting to the full
8337 * associated state */
8338 memcpy(wrqu.ap_addr.sa_data, priv->bssid, ETH_ALEN);
8339 memcpy(&priv->ieee->bssid, priv->bssid, ETH_ALEN);
8340 priv->status &= ~STATUS_ASSOCIATING;
8341 priv->status |= STATUS_ASSOCIATED;
8342 netif_carrier_on(priv->net_dev);
8343 if (netif_queue_stopped(priv->net_dev)) {
8344 IPW_DEBUG_INFO("Waking net queue.\n");
8345 netif_wake_queue(priv->net_dev);
8346 } else {
8347 IPW_DEBUG_INFO("Starting net queue.\n");
8348 netif_start_queue(priv->net_dev);
8349 }
8350 }
8351
8352 if (!(priv->status & STATUS_ASSOCIATED)) {
8353 IPW_DEBUG_WX("Configuring ESSID\n");
8354 down(&priv->action_sem);
8355 /* This is a disassociation event, so kick the firmware to
8356 * look for another AP */
8357 if (priv->config & CFG_STATIC_ESSID)
8358 ipw2100_set_essid(priv, priv->essid, priv->essid_len, 0);
8359 else
8360 ipw2100_set_essid(priv, NULL, 0, 0);
8361 up(&priv->action_sem);
8362 }
8363
8364 wireless_send_event(priv->net_dev, SIOCGIWAP, &wrqu, NULL);
8365}
8366
8367#define IPW2100_FW_MAJOR_VERSION 1
8368#define IPW2100_FW_MINOR_VERSION 3
8369
8370#define IPW2100_FW_MINOR(x) ((x & 0xff) >> 8)
8371#define IPW2100_FW_MAJOR(x) (x & 0xff)
8372
8373#define IPW2100_FW_VERSION ((IPW2100_FW_MINOR_VERSION << 8) | \
8374 IPW2100_FW_MAJOR_VERSION)
8375
8376#define IPW2100_FW_PREFIX "ipw2100-" __stringify(IPW2100_FW_MAJOR_VERSION) \
8377"." __stringify(IPW2100_FW_MINOR_VERSION)
8378
8379#define IPW2100_FW_NAME(x) IPW2100_FW_PREFIX "" x ".fw"
8380
8381
8382/*
8383
8384BINARY FIRMWARE HEADER FORMAT
8385
8386offset length desc
83870 2 version
83882 2 mode == 0:BSS,1:IBSS,2:MONITOR
83894 4 fw_len
83908 4 uc_len
8391C fw_len firmware data
839212 + fw_len uc_len microcode data
8393
8394*/
8395
8396struct ipw2100_fw_header {
8397 short version;
8398 short mode;
8399 unsigned int fw_size;
8400 unsigned int uc_size;
8401} __attribute__ ((packed));
8402
8403
8404
8405static int ipw2100_mod_firmware_load(struct ipw2100_fw *fw)
8406{
8407 struct ipw2100_fw_header *h =
8408 (struct ipw2100_fw_header *)fw->fw_entry->data;
8409
8410 if (IPW2100_FW_MAJOR(h->version) != IPW2100_FW_MAJOR_VERSION) {
8411 printk(KERN_WARNING DRV_NAME ": Firmware image not compatible "
8412 "(detected version id of %u). "
8413 "See Documentation/networking/README.ipw2100\n",
8414 h->version);
8415 return 1;
8416 }
8417
8418 fw->version = h->version;
8419 fw->fw.data = fw->fw_entry->data + sizeof(struct ipw2100_fw_header);
8420 fw->fw.size = h->fw_size;
8421 fw->uc.data = fw->fw.data + h->fw_size;
8422 fw->uc.size = h->uc_size;
8423
8424 return 0;
8425}
8426
8427
8428static int ipw2100_get_firmware(struct ipw2100_priv *priv,
8429 struct ipw2100_fw *fw)
8430{
8431 char *fw_name;
8432 int rc;
8433
8434 IPW_DEBUG_INFO("%s: Using hotplug firmware load.\n",
8435 priv->net_dev->name);
8436
8437 switch (priv->ieee->iw_mode) {
8438 case IW_MODE_ADHOC:
8439 fw_name = IPW2100_FW_NAME("-i");
8440 break;
8441#ifdef CONFIG_IPW2100_MONITOR
8442 case IW_MODE_MONITOR:
8443 fw_name = IPW2100_FW_NAME("-p");
8444 break;
8445#endif
8446 case IW_MODE_INFRA:
8447 default:
8448 fw_name = IPW2100_FW_NAME("");
8449 break;
8450 }
8451
8452 rc = request_firmware(&fw->fw_entry, fw_name, &priv->pci_dev->dev);
8453
8454 if (rc < 0) {
8455 printk(KERN_ERR DRV_NAME ": "
8456 "%s: Firmware '%s' not available or load failed.\n",
8457 priv->net_dev->name, fw_name);
8458 return rc;
8459 }
8460 IPW_DEBUG_INFO("firmware data %p size %zd\n", fw->fw_entry->data,
8461 fw->fw_entry->size);
8462
8463 ipw2100_mod_firmware_load(fw);
8464
8465 return 0;
8466}
8467
8468static void ipw2100_release_firmware(struct ipw2100_priv *priv,
8469 struct ipw2100_fw *fw)
8470{
8471 fw->version = 0;
8472 if (fw->fw_entry)
8473 release_firmware(fw->fw_entry);
8474 fw->fw_entry = NULL;
8475}
8476
8477
8478static int ipw2100_get_fwversion(struct ipw2100_priv *priv, char *buf,
8479 size_t max)
8480{
8481 char ver[MAX_FW_VERSION_LEN];
8482 u32 len = MAX_FW_VERSION_LEN;
8483 u32 tmp;
8484 int i;
8485 /* firmware version is an ascii string (max len of 14) */
8486 if (ipw2100_get_ordinal(priv, IPW_ORD_STAT_FW_VER_NUM,
8487 ver, &len))
8488 return -EIO;
8489 tmp = max;
8490 if (len >= max)
8491 len = max - 1;
8492 for (i = 0; i < len; i++)
8493 buf[i] = ver[i];
8494 buf[i] = '\0';
8495 return tmp;
8496}
8497
8498static int ipw2100_get_ucodeversion(struct ipw2100_priv *priv, char *buf,
8499 size_t max)
8500{
8501 u32 ver;
8502 u32 len = sizeof(ver);
8503 /* microcode version is a 32 bit integer */
8504 if (ipw2100_get_ordinal(priv, IPW_ORD_UCODE_VERSION,
8505 &ver, &len))
8506 return -EIO;
8507 return snprintf(buf, max, "%08X", ver);
8508}
8509
8510/*
8511 * On exit, the firmware will have been freed from the fw list
8512 */
8513static int ipw2100_fw_download(struct ipw2100_priv *priv,
8514 struct ipw2100_fw *fw)
8515{
8516 /* firmware is constructed of N contiguous entries, each entry is
8517 * structured as:
8518 *
8519 * offset sie desc
8520 * 0 4 address to write to
8521 * 4 2 length of data run
8522 * 6 length data
8523 */
8524 unsigned int addr;
8525 unsigned short len;
8526
8527 const unsigned char *firmware_data = fw->fw.data;
8528 unsigned int firmware_data_left = fw->fw.size;
8529
8530 while (firmware_data_left > 0) {
8531 addr = *(u32 *)(firmware_data);
8532 firmware_data += 4;
8533 firmware_data_left -= 4;
8534
8535 len = *(u16 *)(firmware_data);
8536 firmware_data += 2;
8537 firmware_data_left -= 2;
8538
8539 if (len > 32) {
8540 printk(KERN_ERR DRV_NAME ": "
8541 "Invalid firmware run-length of %d bytes\n",
8542 len);
8543 return -EINVAL;
8544 }
8545
8546 write_nic_memory(priv->net_dev, addr, len, firmware_data);
8547 firmware_data += len;
8548 firmware_data_left -= len;
8549 }
8550
8551 return 0;
8552}
8553
8554struct symbol_alive_response {
8555 u8 cmd_id;
8556 u8 seq_num;
8557 u8 ucode_rev;
8558 u8 eeprom_valid;
8559 u16 valid_flags;
8560 u8 IEEE_addr[6];
8561 u16 flags;
8562 u16 pcb_rev;
8563 u16 clock_settle_time; // 1us LSB
8564 u16 powerup_settle_time; // 1us LSB
8565 u16 hop_settle_time; // 1us LSB
8566 u8 date[3]; // month, day, year
8567 u8 time[2]; // hours, minutes
8568 u8 ucode_valid;
8569};
8570
8571static int ipw2100_ucode_download(struct ipw2100_priv *priv,
8572 struct ipw2100_fw *fw)
8573{
8574 struct net_device *dev = priv->net_dev;
8575 const unsigned char *microcode_data = fw->uc.data;
8576 unsigned int microcode_data_left = fw->uc.size;
8577
8578 struct symbol_alive_response response;
8579 int i, j;
8580 u8 data;
8581
8582 /* Symbol control */
8583 write_nic_word(dev, IPW2100_CONTROL_REG, 0x703);
8584 readl((void *)(dev->base_addr));
8585 write_nic_word(dev, IPW2100_CONTROL_REG, 0x707);
8586 readl((void *)(dev->base_addr));
8587
8588 /* HW config */
8589 write_nic_byte(dev, 0x210014, 0x72); /* fifo width =16 */
8590 readl((void *)(dev->base_addr));
8591 write_nic_byte(dev, 0x210014, 0x72); /* fifo width =16 */
8592 readl((void *)(dev->base_addr));
8593
8594 /* EN_CS_ACCESS bit to reset control store pointer */
8595 write_nic_byte(dev, 0x210000, 0x40);
8596 readl((void *)(dev->base_addr));
8597 write_nic_byte(dev, 0x210000, 0x0);
8598 readl((void *)(dev->base_addr));
8599 write_nic_byte(dev, 0x210000, 0x40);
8600 readl((void *)(dev->base_addr));
8601
8602 /* copy microcode from buffer into Symbol */
8603
8604 while (microcode_data_left > 0) {
8605 write_nic_byte(dev, 0x210010, *microcode_data++);
8606 write_nic_byte(dev, 0x210010, *microcode_data++);
8607 microcode_data_left -= 2;
8608 }
8609
8610 /* EN_CS_ACCESS bit to reset the control store pointer */
8611 write_nic_byte(dev, 0x210000, 0x0);
8612 readl((void *)(dev->base_addr));
8613
8614 /* Enable System (Reg 0)
8615 * first enable causes garbage in RX FIFO */
8616 write_nic_byte(dev, 0x210000, 0x0);
8617 readl((void *)(dev->base_addr));
8618 write_nic_byte(dev, 0x210000, 0x80);
8619 readl((void *)(dev->base_addr));
8620
8621 /* Reset External Baseband Reg */
8622 write_nic_word(dev, IPW2100_CONTROL_REG, 0x703);
8623 readl((void *)(dev->base_addr));
8624 write_nic_word(dev, IPW2100_CONTROL_REG, 0x707);
8625 readl((void *)(dev->base_addr));
8626
8627 /* HW Config (Reg 5) */
8628 write_nic_byte(dev, 0x210014, 0x72); // fifo width =16
8629 readl((void *)(dev->base_addr));
8630 write_nic_byte(dev, 0x210014, 0x72); // fifo width =16
8631 readl((void *)(dev->base_addr));
8632
8633 /* Enable System (Reg 0)
8634 * second enable should be OK */
8635 write_nic_byte(dev, 0x210000, 0x00); // clear enable system
8636 readl((void *)(dev->base_addr));
8637 write_nic_byte(dev, 0x210000, 0x80); // set enable system
8638
8639 /* check Symbol is enabled - upped this from 5 as it wasn't always
8640 * catching the update */
8641 for (i = 0; i < 10; i++) {
8642 udelay(10);
8643
8644 /* check Dino is enabled bit */
8645 read_nic_byte(dev, 0x210000, &data);
8646 if (data & 0x1)
8647 break;
8648 }
8649
8650 if (i == 10) {
8651 printk(KERN_ERR DRV_NAME ": %s: Error initializing Symbol\n",
8652 dev->name);
8653 return -EIO;
8654 }
8655
8656 /* Get Symbol alive response */
8657 for (i = 0; i < 30; i++) {
8658 /* Read alive response structure */
8659 for (j = 0;
8660 j < (sizeof(struct symbol_alive_response) >> 1);
8661 j++)
8662 read_nic_word(dev, 0x210004,
8663 ((u16 *)&response) + j);
8664
8665 if ((response.cmd_id == 1) &&
8666 (response.ucode_valid == 0x1))
8667 break;
8668 udelay(10);
8669 }
8670
8671 if (i == 30) {
8672 printk(KERN_ERR DRV_NAME ": %s: No response from Symbol - hw not alive\n",
8673 dev->name);
8674 printk_buf(IPW_DL_ERROR, (u8*)&response, sizeof(response));
8675 return -EIO;
8676 }
8677
8678 return 0;
8679}
diff --git a/drivers/net/wireless/ipw2100.h b/drivers/net/wireless/ipw2100.h
new file mode 100644
index 000000000000..2a3cdbd50168
--- /dev/null
+++ b/drivers/net/wireless/ipw2100.h
@@ -0,0 +1,1167 @@
1/******************************************************************************
2
3 Copyright(c) 2003 - 2005 Intel Corporation. All rights reserved.
4
5 This program is free software; you can redistribute it and/or modify it
6 under the terms of version 2 of the GNU General Public License as
7 published by the Free Software Foundation.
8
9 This program is distributed in the hope that it will be useful, but WITHOUT
10 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11 FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
12 more details.
13
14 You should have received a copy of the GNU General Public License along with
15 this program; if not, write to the Free Software Foundation, Inc., 59
16 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
17
18 The full GNU General Public License is included in this distribution in the
19 file called LICENSE.
20
21 Contact Information:
22 James P. Ketrenos <ipw2100-admin@linux.intel.com>
23 Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497
24
25******************************************************************************/
26#ifndef _IPW2100_H
27#define _IPW2100_H
28
29#include <linux/sched.h>
30#include <linux/interrupt.h>
31#include <linux/netdevice.h>
32#include <linux/etherdevice.h>
33#include <linux/list.h>
34#include <linux/delay.h>
35#include <linux/skbuff.h>
36#include <asm/io.h>
37#include <linux/socket.h>
38#include <linux/if_arp.h>
39#include <linux/wireless.h>
40#include <linux/version.h>
41#include <net/iw_handler.h> // new driver API
42
43#include <net/ieee80211.h>
44
45#include <linux/workqueue.h>
46
47struct ipw2100_priv;
48struct ipw2100_tx_packet;
49struct ipw2100_rx_packet;
50
51#define IPW_DL_UNINIT 0x80000000
52#define IPW_DL_NONE 0x00000000
53#define IPW_DL_ALL 0x7FFFFFFF
54
55/*
56 * To use the debug system;
57 *
58 * If you are defining a new debug classification, simply add it to the #define
59 * list here in the form of:
60 *
61 * #define IPW_DL_xxxx VALUE
62 *
63 * shifting value to the left one bit from the previous entry. xxxx should be
64 * the name of the classification (for example, WEP)
65 *
66 * You then need to either add a IPW2100_xxxx_DEBUG() macro definition for your
67 * classification, or use IPW_DEBUG(IPW_DL_xxxx, ...) whenever you want
68 * to send output to that classification.
69 *
70 * To add your debug level to the list of levels seen when you perform
71 *
72 * % cat /proc/net/ipw2100/debug_level
73 *
74 * you simply need to add your entry to the ipw2100_debug_levels array.
75 *
76 * If you do not see debug_level in /proc/net/ipw2100 then you do not have
77 * CONFIG_IPW_DEBUG defined in your kernel configuration
78 *
79 */
80
81#define IPW_DL_ERROR (1<<0)
82#define IPW_DL_WARNING (1<<1)
83#define IPW_DL_INFO (1<<2)
84#define IPW_DL_WX (1<<3)
85#define IPW_DL_HC (1<<5)
86#define IPW_DL_STATE (1<<6)
87
88#define IPW_DL_NOTIF (1<<10)
89#define IPW_DL_SCAN (1<<11)
90#define IPW_DL_ASSOC (1<<12)
91#define IPW_DL_DROP (1<<13)
92
93#define IPW_DL_IOCTL (1<<14)
94#define IPW_DL_RF_KILL (1<<17)
95
96
97#define IPW_DL_MANAGE (1<<15)
98#define IPW_DL_FW (1<<16)
99
100#define IPW_DL_FRAG (1<<21)
101#define IPW_DL_WEP (1<<22)
102#define IPW_DL_TX (1<<23)
103#define IPW_DL_RX (1<<24)
104#define IPW_DL_ISR (1<<25)
105#define IPW_DL_IO (1<<26)
106#define IPW_DL_TRACE (1<<28)
107
108#define IPW_DEBUG_ERROR(f, a...) printk(KERN_ERR DRV_NAME ": " f, ## a)
109#define IPW_DEBUG_WARNING(f, a...) printk(KERN_WARNING DRV_NAME ": " f, ## a)
110#define IPW_DEBUG_INFO(f...) IPW_DEBUG(IPW_DL_INFO, ## f)
111#define IPW_DEBUG_WX(f...) IPW_DEBUG(IPW_DL_WX, ## f)
112#define IPW_DEBUG_SCAN(f...) IPW_DEBUG(IPW_DL_SCAN, ## f)
113#define IPW_DEBUG_NOTIF(f...) IPW_DEBUG(IPW_DL_NOTIF, ## f)
114#define IPW_DEBUG_TRACE(f...) IPW_DEBUG(IPW_DL_TRACE, ## f)
115#define IPW_DEBUG_RX(f...) IPW_DEBUG(IPW_DL_RX, ## f)
116#define IPW_DEBUG_TX(f...) IPW_DEBUG(IPW_DL_TX, ## f)
117#define IPW_DEBUG_ISR(f...) IPW_DEBUG(IPW_DL_ISR, ## f)
118#define IPW_DEBUG_MANAGEMENT(f...) IPW_DEBUG(IPW_DL_MANAGE, ## f)
119#define IPW_DEBUG_WEP(f...) IPW_DEBUG(IPW_DL_WEP, ## f)
120#define IPW_DEBUG_HC(f...) IPW_DEBUG(IPW_DL_HC, ## f)
121#define IPW_DEBUG_FRAG(f...) IPW_DEBUG(IPW_DL_FRAG, ## f)
122#define IPW_DEBUG_FW(f...) IPW_DEBUG(IPW_DL_FW, ## f)
123#define IPW_DEBUG_RF_KILL(f...) IPW_DEBUG(IPW_DL_RF_KILL, ## f)
124#define IPW_DEBUG_DROP(f...) IPW_DEBUG(IPW_DL_DROP, ## f)
125#define IPW_DEBUG_IO(f...) IPW_DEBUG(IPW_DL_IO, ## f)
126#define IPW_DEBUG_IOCTL(f...) IPW_DEBUG(IPW_DL_IOCTL, ## f)
127#define IPW_DEBUG_STATE(f, a...) IPW_DEBUG(IPW_DL_STATE | IPW_DL_ASSOC | IPW_DL_INFO, f, ## a)
128#define IPW_DEBUG_ASSOC(f, a...) IPW_DEBUG(IPW_DL_ASSOC | IPW_DL_INFO, f, ## a)
129
130enum {
131 IPW_HW_STATE_DISABLED = 1,
132 IPW_HW_STATE_ENABLED = 0
133};
134
135struct ssid_context {
136 char ssid[IW_ESSID_MAX_SIZE + 1];
137 int ssid_len;
138 unsigned char bssid[ETH_ALEN];
139 int port_type;
140 int channel;
141
142};
143
144extern const char *port_type_str[];
145extern const char *band_str[];
146
147#define NUMBER_OF_BD_PER_COMMAND_PACKET 1
148#define NUMBER_OF_BD_PER_DATA_PACKET 2
149
150#define IPW_MAX_BDS 6
151#define NUMBER_OF_OVERHEAD_BDS_PER_PACKETR 2
152#define NUMBER_OF_BDS_TO_LEAVE_FOR_COMMANDS 1
153
154#define REQUIRED_SPACE_IN_RING_FOR_COMMAND_PACKET \
155 (IPW_BD_QUEUE_W_R_MIN_SPARE + NUMBER_OF_BD_PER_COMMAND_PACKET)
156
157struct bd_status {
158 union {
159 struct { u8 nlf:1, txType:2, intEnabled:1, reserved:4;} fields;
160 u8 field;
161 } info;
162} __attribute__ ((packed));
163
164struct ipw2100_bd {
165 u32 host_addr;
166 u32 buf_length;
167 struct bd_status status;
168 /* number of fragments for frame (should be set only for
169 * 1st TBD) */
170 u8 num_fragments;
171 u8 reserved[6];
172} __attribute__ ((packed));
173
174#define IPW_BD_QUEUE_LENGTH(n) (1<<n)
175#define IPW_BD_ALIGNMENT(L) (L*sizeof(struct ipw2100_bd))
176
177#define IPW_BD_STATUS_TX_FRAME_802_3 0x00
178#define IPW_BD_STATUS_TX_FRAME_NOT_LAST_FRAGMENT 0x01
179#define IPW_BD_STATUS_TX_FRAME_COMMAND 0x02
180#define IPW_BD_STATUS_TX_FRAME_802_11 0x04
181#define IPW_BD_STATUS_TX_INTERRUPT_ENABLE 0x08
182
183struct ipw2100_bd_queue {
184 /* driver (virtual) pointer to queue */
185 struct ipw2100_bd *drv;
186
187 /* firmware (physical) pointer to queue */
188 dma_addr_t nic;
189
190 /* Length of phy memory allocated for BDs */
191 u32 size;
192
193 /* Number of BDs in queue (and in array) */
194 u32 entries;
195
196 /* Number of available BDs (invalid for NIC BDs) */
197 u32 available;
198
199 /* Offset of oldest used BD in array (next one to
200 * check for completion) */
201 u32 oldest;
202
203 /* Offset of next available (unused) BD */
204 u32 next;
205};
206
207#define RX_QUEUE_LENGTH 256
208#define TX_QUEUE_LENGTH 256
209#define HW_QUEUE_LENGTH 256
210
211#define TX_PENDED_QUEUE_LENGTH (TX_QUEUE_LENGTH / NUMBER_OF_BD_PER_DATA_PACKET)
212
213#define STATUS_TYPE_MASK 0x0000000f
214#define COMMAND_STATUS_VAL 0
215#define STATUS_CHANGE_VAL 1
216#define P80211_DATA_VAL 2
217#define P8023_DATA_VAL 3
218#define HOST_NOTIFICATION_VAL 4
219
220#define IPW2100_RSSI_TO_DBM (-98)
221
222struct ipw2100_status {
223 u32 frame_size;
224 u16 status_fields;
225 u8 flags;
226#define IPW_STATUS_FLAG_DECRYPTED (1<<0)
227#define IPW_STATUS_FLAG_WEP_ENCRYPTED (1<<1)
228#define IPW_STATUS_FLAG_CRC_ERROR (1<<2)
229 u8 rssi;
230} __attribute__ ((packed));
231
232struct ipw2100_status_queue {
233 /* driver (virtual) pointer to queue */
234 struct ipw2100_status *drv;
235
236 /* firmware (physical) pointer to queue */
237 dma_addr_t nic;
238
239 /* Length of phy memory allocated for BDs */
240 u32 size;
241};
242
243#define HOST_COMMAND_PARAMS_REG_LEN 100
244#define CMD_STATUS_PARAMS_REG_LEN 3
245
246#define IPW_WPA_CAPABILITIES 0x1
247#define IPW_WPA_LISTENINTERVAL 0x2
248#define IPW_WPA_AP_ADDRESS 0x4
249
250#define IPW_MAX_VAR_IE_LEN ((HOST_COMMAND_PARAMS_REG_LEN - 4) * sizeof(u32))
251
252struct ipw2100_wpa_assoc_frame {
253 u16 fixed_ie_mask;
254 struct {
255 u16 capab_info;
256 u16 listen_interval;
257 u8 current_ap[ETH_ALEN];
258 } fixed_ies;
259 u32 var_ie_len;
260 u8 var_ie[IPW_MAX_VAR_IE_LEN];
261};
262
263#define IPW_BSS 1
264#define IPW_MONITOR 2
265#define IPW_IBSS 3
266
267/**
268 * @struct _tx_cmd - HWCommand
269 * @brief H/W command structure.
270 */
271struct ipw2100_cmd_header {
272 u32 host_command_reg;
273 u32 host_command_reg1;
274 u32 sequence;
275 u32 host_command_len_reg;
276 u32 host_command_params_reg[HOST_COMMAND_PARAMS_REG_LEN];
277 u32 cmd_status_reg;
278 u32 cmd_status_params_reg[CMD_STATUS_PARAMS_REG_LEN];
279 u32 rxq_base_ptr;
280 u32 rxq_next_ptr;
281 u32 rxq_host_ptr;
282 u32 txq_base_ptr;
283 u32 txq_next_ptr;
284 u32 txq_host_ptr;
285 u32 tx_status_reg;
286 u32 reserved;
287 u32 status_change_reg;
288 u32 reserved1[3];
289 u32 *ordinal1_ptr;
290 u32 *ordinal2_ptr;
291} __attribute__ ((packed));
292
293struct ipw2100_data_header {
294 u32 host_command_reg;
295 u32 host_command_reg1;
296 u8 encrypted; // BOOLEAN in win! TRUE if frame is enc by driver
297 u8 needs_encryption; // BOOLEAN in win! TRUE if frma need to be enc in NIC
298 u8 wep_index; // 0 no key, 1-4 key index, 0xff immediate key
299 u8 key_size; // 0 no imm key, 0x5 64bit encr, 0xd 128bit encr, 0x10 128bit encr and 128bit IV
300 u8 key[16];
301 u8 reserved[10]; // f/w reserved
302 u8 src_addr[ETH_ALEN];
303 u8 dst_addr[ETH_ALEN];
304 u16 fragment_size;
305} __attribute__ ((packed));
306
307/* Host command data structure */
308struct host_command {
309 u32 host_command; // COMMAND ID
310 u32 host_command1; // COMMAND ID
311 u32 host_command_sequence; // UNIQUE COMMAND NUMBER (ID)
312 u32 host_command_length; // LENGTH
313 u32 host_command_parameters[HOST_COMMAND_PARAMS_REG_LEN]; // COMMAND PARAMETERS
314} __attribute__ ((packed));
315
316
317typedef enum {
318 POWER_ON_RESET,
319 EXIT_POWER_DOWN_RESET,
320 SW_RESET,
321 EEPROM_RW,
322 SW_RE_INIT
323} ipw2100_reset_event;
324
325enum {
326 COMMAND = 0xCAFE,
327 DATA,
328 RX
329};
330
331
332struct ipw2100_tx_packet {
333 int type;
334 int index;
335 union {
336 struct { /* COMMAND */
337 struct ipw2100_cmd_header* cmd;
338 dma_addr_t cmd_phys;
339 } c_struct;
340 struct { /* DATA */
341 struct ipw2100_data_header* data;
342 dma_addr_t data_phys;
343 struct ieee80211_txb *txb;
344 } d_struct;
345 } info;
346 int jiffy_start;
347
348 struct list_head list;
349};
350
351
352struct ipw2100_rx_packet {
353 struct ipw2100_rx *rxp;
354 dma_addr_t dma_addr;
355 int jiffy_start;
356 struct sk_buff *skb;
357 struct list_head list;
358};
359
360#define FRAG_DISABLED (1<<31)
361#define RTS_DISABLED (1<<31)
362#define MAX_RTS_THRESHOLD 2304U
363#define MIN_RTS_THRESHOLD 1U
364#define DEFAULT_RTS_THRESHOLD 1000U
365
366#define DEFAULT_BEACON_INTERVAL 100U
367#define DEFAULT_SHORT_RETRY_LIMIT 7U
368#define DEFAULT_LONG_RETRY_LIMIT 4U
369
370struct ipw2100_ordinals {
371 u32 table1_addr;
372 u32 table2_addr;
373 u32 table1_size;
374 u32 table2_size;
375};
376
377/* Host Notification header */
378struct ipw2100_notification {
379 u32 hnhdr_subtype; /* type of host notification */
380 u32 hnhdr_size; /* size in bytes of data
381 or number of entries, if table.
382 Does NOT include header */
383} __attribute__ ((packed));
384
385#define MAX_KEY_SIZE 16
386#define MAX_KEYS 8
387
388#define IPW2100_WEP_ENABLE (1<<1)
389#define IPW2100_WEP_DROP_CLEAR (1<<2)
390
391#define IPW_NONE_CIPHER (1<<0)
392#define IPW_WEP40_CIPHER (1<<1)
393#define IPW_TKIP_CIPHER (1<<2)
394#define IPW_CCMP_CIPHER (1<<4)
395#define IPW_WEP104_CIPHER (1<<5)
396#define IPW_CKIP_CIPHER (1<<6)
397
398#define IPW_AUTH_OPEN 0
399#define IPW_AUTH_SHARED 1
400
401struct statistic {
402 int value;
403 int hi;
404 int lo;
405};
406
407#define INIT_STAT(x) do { \
408 (x)->value = (x)->hi = 0; \
409 (x)->lo = 0x7fffffff; \
410} while (0)
411#define SET_STAT(x,y) do { \
412 (x)->value = y; \
413 if ((x)->value > (x)->hi) (x)->hi = (x)->value; \
414 if ((x)->value < (x)->lo) (x)->lo = (x)->value; \
415} while (0)
416#define INC_STAT(x) do { if (++(x)->value > (x)->hi) (x)->hi = (x)->value; } \
417while (0)
418#define DEC_STAT(x) do { if (--(x)->value < (x)->lo) (x)->lo = (x)->value; } \
419while (0)
420
421#define IPW2100_ERROR_QUEUE 5
422
423/* Power management code: enable or disable? */
424enum {
425#ifdef CONFIG_PM
426 IPW2100_PM_DISABLED = 0,
427 PM_STATE_SIZE = 16,
428#else
429 IPW2100_PM_DISABLED = 1,
430 PM_STATE_SIZE = 0,
431#endif
432};
433
434#define STATUS_POWERED (1<<0)
435#define STATUS_CMD_ACTIVE (1<<1) /**< host command in progress */
436#define STATUS_RUNNING (1<<2) /* Card initialized, but not enabled */
437#define STATUS_ENABLED (1<<3) /* Card enabled -- can scan,Tx,Rx */
438#define STATUS_STOPPING (1<<4) /* Card is in shutdown phase */
439#define STATUS_INITIALIZED (1<<5) /* Card is ready for external calls */
440#define STATUS_ASSOCIATING (1<<9) /* Associated, but no BSSID yet */
441#define STATUS_ASSOCIATED (1<<10) /* Associated and BSSID valid */
442#define STATUS_INT_ENABLED (1<<11)
443#define STATUS_RF_KILL_HW (1<<12)
444#define STATUS_RF_KILL_SW (1<<13)
445#define STATUS_RF_KILL_MASK (STATUS_RF_KILL_HW | STATUS_RF_KILL_SW)
446#define STATUS_EXIT_PENDING (1<<14)
447
448#define STATUS_SCAN_PENDING (1<<23)
449#define STATUS_SCANNING (1<<24)
450#define STATUS_SCAN_ABORTING (1<<25)
451#define STATUS_SCAN_COMPLETE (1<<26)
452#define STATUS_WX_EVENT_PENDING (1<<27)
453#define STATUS_RESET_PENDING (1<<29)
454#define STATUS_SECURITY_UPDATED (1<<30) /* Security sync needed */
455
456
457
458/* Internal NIC states */
459#define IPW_STATE_INITIALIZED (1<<0)
460#define IPW_STATE_COUNTRY_FOUND (1<<1)
461#define IPW_STATE_ASSOCIATED (1<<2)
462#define IPW_STATE_ASSN_LOST (1<<3)
463#define IPW_STATE_ASSN_CHANGED (1<<4)
464#define IPW_STATE_SCAN_COMPLETE (1<<5)
465#define IPW_STATE_ENTERED_PSP (1<<6)
466#define IPW_STATE_LEFT_PSP (1<<7)
467#define IPW_STATE_RF_KILL (1<<8)
468#define IPW_STATE_DISABLED (1<<9)
469#define IPW_STATE_POWER_DOWN (1<<10)
470#define IPW_STATE_SCANNING (1<<11)
471
472
473
474#define CFG_STATIC_CHANNEL (1<<0) /* Restrict assoc. to single channel */
475#define CFG_STATIC_ESSID (1<<1) /* Restrict assoc. to single SSID */
476#define CFG_STATIC_BSSID (1<<2) /* Restrict assoc. to single BSSID */
477#define CFG_CUSTOM_MAC (1<<3)
478#define CFG_LONG_PREAMBLE (1<<4)
479#define CFG_ASSOCIATE (1<<6)
480#define CFG_FIXED_RATE (1<<7)
481#define CFG_ADHOC_CREATE (1<<8)
482#define CFG_C3_DISABLED (1<<9)
483#define CFG_PASSIVE_SCAN (1<<10)
484
485#define CAP_SHARED_KEY (1<<0) /* Off = OPEN */
486#define CAP_PRIVACY_ON (1<<1) /* Off = No privacy */
487
488struct ipw2100_priv {
489
490 int stop_hang_check; /* Set 1 when shutting down to kill hang_check */
491 int stop_rf_kill; /* Set 1 when shutting down to kill rf_kill */
492
493 struct ieee80211_device *ieee;
494 unsigned long status;
495 unsigned long config;
496 unsigned long capability;
497
498 /* Statistics */
499 int resets;
500 int reset_backoff;
501
502 /* Context */
503 u8 essid[IW_ESSID_MAX_SIZE];
504 u8 essid_len;
505 u8 bssid[ETH_ALEN];
506 u8 channel;
507 int last_mode;
508 int cstate_limit;
509
510 unsigned long connect_start;
511 unsigned long last_reset;
512
513 u32 channel_mask;
514 u32 fatal_error;
515 u32 fatal_errors[IPW2100_ERROR_QUEUE];
516 u32 fatal_index;
517 int eeprom_version;
518 int firmware_version;
519 unsigned long hw_features;
520 int hangs;
521 u32 last_rtc;
522 int dump_raw; /* 1 to dump raw bytes in /sys/.../memory */
523 u8* snapshot[0x30];
524
525 u8 mandatory_bssid_mac[ETH_ALEN];
526 u8 mac_addr[ETH_ALEN];
527
528 int power_mode;
529
530 /* WEP data */
531 struct ieee80211_security sec;
532 int messages_sent;
533
534
535 int short_retry_limit;
536 int long_retry_limit;
537
538 u32 rts_threshold;
539 u32 frag_threshold;
540
541 int in_isr;
542
543 u32 tx_rates;
544 int tx_power;
545 u32 beacon_interval;
546
547 char nick[IW_ESSID_MAX_SIZE + 1];
548
549 struct ipw2100_status_queue status_queue;
550
551 struct statistic txq_stat;
552 struct statistic rxq_stat;
553 struct ipw2100_bd_queue rx_queue;
554 struct ipw2100_bd_queue tx_queue;
555 struct ipw2100_rx_packet *rx_buffers;
556
557 struct statistic fw_pend_stat;
558 struct list_head fw_pend_list;
559
560 struct statistic msg_free_stat;
561 struct statistic msg_pend_stat;
562 struct list_head msg_free_list;
563 struct list_head msg_pend_list;
564 struct ipw2100_tx_packet *msg_buffers;
565
566 struct statistic tx_free_stat;
567 struct statistic tx_pend_stat;
568 struct list_head tx_free_list;
569 struct list_head tx_pend_list;
570 struct ipw2100_tx_packet *tx_buffers;
571
572 struct ipw2100_ordinals ordinals;
573
574 struct pci_dev *pci_dev;
575
576 struct proc_dir_entry *dir_dev;
577
578 struct net_device *net_dev;
579 struct iw_statistics wstats;
580
581 struct tasklet_struct irq_tasklet;
582
583 struct workqueue_struct *workqueue;
584 struct work_struct reset_work;
585 struct work_struct security_work;
586 struct work_struct wx_event_work;
587 struct work_struct hang_check;
588 struct work_struct rf_kill;
589
590 u32 interrupts;
591 int tx_interrupts;
592 int rx_interrupts;
593 int inta_other;
594
595 spinlock_t low_lock;
596 struct semaphore action_sem;
597 struct semaphore adapter_sem;
598
599 wait_queue_head_t wait_command_queue;
600};
601
602
603/*********************************************************
604 * Host Command -> From Driver to FW
605 *********************************************************/
606
607/**
608 * Host command identifiers
609 */
610#define HOST_COMPLETE 2
611#define SYSTEM_CONFIG 6
612#define SSID 8
613#define MANDATORY_BSSID 9
614#define AUTHENTICATION_TYPE 10
615#define ADAPTER_ADDRESS 11
616#define PORT_TYPE 12
617#define INTERNATIONAL_MODE 13
618#define CHANNEL 14
619#define RTS_THRESHOLD 15
620#define FRAG_THRESHOLD 16
621#define POWER_MODE 17
622#define TX_RATES 18
623#define BASIC_TX_RATES 19
624#define WEP_KEY_INFO 20
625#define WEP_KEY_INDEX 25
626#define WEP_FLAGS 26
627#define ADD_MULTICAST 27
628#define CLEAR_ALL_MULTICAST 28
629#define BEACON_INTERVAL 29
630#define ATIM_WINDOW 30
631#define CLEAR_STATISTICS 31
632#define SEND 33
633#define TX_POWER_INDEX 36
634#define BROADCAST_SCAN 43
635#define CARD_DISABLE 44
636#define PREFERRED_BSSID 45
637#define SET_SCAN_OPTIONS 46
638#define SCAN_DWELL_TIME 47
639#define SWEEP_TABLE 48
640#define AP_OR_STATION_TABLE 49
641#define GROUP_ORDINALS 50
642#define SHORT_RETRY_LIMIT 51
643#define LONG_RETRY_LIMIT 52
644
645#define HOST_PRE_POWER_DOWN 58
646#define CARD_DISABLE_PHY_OFF 61
647#define MSDU_TX_RATES 62
648
649
650/* Rogue AP Detection */
651#define SET_STATION_STAT_BITS 64
652#define CLEAR_STATIONS_STAT_BITS 65
653#define LEAP_ROGUE_MODE 66 //TODO tbw replaced by CFG_LEAP_ROGUE_AP
654#define SET_SECURITY_INFORMATION 67
655#define DISASSOCIATION_BSSID 68
656#define SET_WPA_IE 69
657
658
659
660/* system configuration bit mask: */
661#define IPW_CFG_MONITOR 0x00004
662#define IPW_CFG_PREAMBLE_AUTO 0x00010
663#define IPW_CFG_IBSS_AUTO_START 0x00020
664#define IPW_CFG_LOOPBACK 0x00100
665#define IPW_CFG_ANSWER_BCSSID_PROBE 0x00800
666#define IPW_CFG_BT_SIDEBAND_SIGNAL 0x02000
667#define IPW_CFG_802_1x_ENABLE 0x04000
668#define IPW_CFG_BSS_MASK 0x08000
669#define IPW_CFG_IBSS_MASK 0x10000
670
671#define IPW_SCAN_NOASSOCIATE (1<<0)
672#define IPW_SCAN_MIXED_CELL (1<<1)
673/* RESERVED (1<<2) */
674#define IPW_SCAN_PASSIVE (1<<3)
675
676#define IPW_NIC_FATAL_ERROR 0x2A7F0
677#define IPW_ERROR_ADDR(x) (x & 0x3FFFF)
678#define IPW_ERROR_CODE(x) ((x & 0xFF000000) >> 24)
679#define IPW2100_ERR_C3_CORRUPTION (0x10 << 24)
680#define IPW2100_ERR_MSG_TIMEOUT (0x11 << 24)
681#define IPW2100_ERR_FW_LOAD (0x12 << 24)
682
683#define IPW_MEM_SRAM_HOST_SHARED_LOWER_BOUND 0x200
684#define IPW_MEM_SRAM_HOST_INTERRUPT_AREA_LOWER_BOUND IPW_MEM_SRAM_HOST_SHARED_LOWER_BOUND + 0x0D80
685
686#define IPW_MEM_HOST_SHARED_RX_BD_BASE (IPW_MEM_SRAM_HOST_SHARED_LOWER_BOUND + 0x40)
687#define IPW_MEM_HOST_SHARED_RX_STATUS_BASE (IPW_MEM_SRAM_HOST_SHARED_LOWER_BOUND + 0x44)
688#define IPW_MEM_HOST_SHARED_RX_BD_SIZE (IPW_MEM_SRAM_HOST_SHARED_LOWER_BOUND + 0x48)
689#define IPW_MEM_HOST_SHARED_RX_READ_INDEX (IPW_MEM_SRAM_HOST_SHARED_LOWER_BOUND + 0xa0)
690
691#define IPW_MEM_HOST_SHARED_TX_QUEUE_BD_BASE (IPW_MEM_SRAM_HOST_SHARED_LOWER_BOUND + 0x00)
692#define IPW_MEM_HOST_SHARED_TX_QUEUE_BD_SIZE (IPW_MEM_SRAM_HOST_SHARED_LOWER_BOUND + 0x04)
693#define IPW_MEM_HOST_SHARED_TX_QUEUE_READ_INDEX (IPW_MEM_SRAM_HOST_SHARED_LOWER_BOUND + 0x80)
694
695#define IPW_MEM_HOST_SHARED_RX_WRITE_INDEX \
696 (IPW_MEM_SRAM_HOST_INTERRUPT_AREA_LOWER_BOUND + 0x20)
697
698#define IPW_MEM_HOST_SHARED_TX_QUEUE_WRITE_INDEX \
699 (IPW_MEM_SRAM_HOST_INTERRUPT_AREA_LOWER_BOUND)
700
701#define IPW_MEM_HOST_SHARED_ORDINALS_TABLE_1 (IPW_MEM_SRAM_HOST_SHARED_LOWER_BOUND + 0x180)
702#define IPW_MEM_HOST_SHARED_ORDINALS_TABLE_2 (IPW_MEM_SRAM_HOST_SHARED_LOWER_BOUND + 0x184)
703
704#define IPW2100_INTA_TX_TRANSFER (0x00000001) // Bit 0 (LSB)
705#define IPW2100_INTA_RX_TRANSFER (0x00000002) // Bit 1
706#define IPW2100_INTA_TX_COMPLETE (0x00000004) // Bit 2
707#define IPW2100_INTA_EVENT_INTERRUPT (0x00000008) // Bit 3
708#define IPW2100_INTA_STATUS_CHANGE (0x00000010) // Bit 4
709#define IPW2100_INTA_BEACON_PERIOD_EXPIRED (0x00000020) // Bit 5
710#define IPW2100_INTA_SLAVE_MODE_HOST_COMMAND_DONE (0x00010000) // Bit 16
711#define IPW2100_INTA_FW_INIT_DONE (0x01000000) // Bit 24
712#define IPW2100_INTA_FW_CALIBRATION_CALC (0x02000000) // Bit 25
713#define IPW2100_INTA_FATAL_ERROR (0x40000000) // Bit 30
714#define IPW2100_INTA_PARITY_ERROR (0x80000000) // Bit 31 (MSB)
715
716#define IPW_AUX_HOST_RESET_REG_PRINCETON_RESET (0x00000001)
717#define IPW_AUX_HOST_RESET_REG_FORCE_NMI (0x00000002)
718#define IPW_AUX_HOST_RESET_REG_PCI_HOST_CLUSTER_FATAL_NMI (0x00000004)
719#define IPW_AUX_HOST_RESET_REG_CORE_FATAL_NMI (0x00000008)
720#define IPW_AUX_HOST_RESET_REG_SW_RESET (0x00000080)
721#define IPW_AUX_HOST_RESET_REG_MASTER_DISABLED (0x00000100)
722#define IPW_AUX_HOST_RESET_REG_STOP_MASTER (0x00000200)
723
724#define IPW_AUX_HOST_GP_CNTRL_BIT_CLOCK_READY (0x00000001) // Bit 0 (LSB)
725#define IPW_AUX_HOST_GP_CNTRL_BIT_HOST_ALLOWS_STANDBY (0x00000002) // Bit 1
726#define IPW_AUX_HOST_GP_CNTRL_BIT_INIT_DONE (0x00000004) // Bit 2
727#define IPW_AUX_HOST_GP_CNTRL_BITS_SYS_CONFIG (0x000007c0) // Bits 6-10
728#define IPW_AUX_HOST_GP_CNTRL_BIT_BUS_TYPE (0x00000200) // Bit 9
729#define IPW_AUX_HOST_GP_CNTRL_BIT_BAR0_BLOCK_SIZE (0x00000400) // Bit 10
730#define IPW_AUX_HOST_GP_CNTRL_BIT_USB_MODE (0x20000000) // Bit 29
731#define IPW_AUX_HOST_GP_CNTRL_BIT_HOST_FORCES_SYS_CLK (0x40000000) // Bit 30
732#define IPW_AUX_HOST_GP_CNTRL_BIT_FW_FORCES_SYS_CLK (0x80000000) // Bit 31 (MSB)
733
734#define IPW_BIT_GPIO_GPIO1_MASK 0x0000000C
735#define IPW_BIT_GPIO_GPIO3_MASK 0x000000C0
736#define IPW_BIT_GPIO_GPIO1_ENABLE 0x00000008
737#define IPW_BIT_GPIO_RF_KILL 0x00010000
738
739#define IPW_BIT_GPIO_LED_OFF 0x00002000 // Bit 13 = 1
740
741#define IPW_REG_DOMAIN_0_OFFSET 0x0000
742#define IPW_REG_DOMAIN_1_OFFSET IPW_MEM_SRAM_HOST_SHARED_LOWER_BOUND
743
744#define IPW_REG_INTA IPW_REG_DOMAIN_0_OFFSET + 0x0008
745#define IPW_REG_INTA_MASK IPW_REG_DOMAIN_0_OFFSET + 0x000C
746#define IPW_REG_INDIRECT_ACCESS_ADDRESS IPW_REG_DOMAIN_0_OFFSET + 0x0010
747#define IPW_REG_INDIRECT_ACCESS_DATA IPW_REG_DOMAIN_0_OFFSET + 0x0014
748#define IPW_REG_AUTOINCREMENT_ADDRESS IPW_REG_DOMAIN_0_OFFSET + 0x0018
749#define IPW_REG_AUTOINCREMENT_DATA IPW_REG_DOMAIN_0_OFFSET + 0x001C
750#define IPW_REG_RESET_REG IPW_REG_DOMAIN_0_OFFSET + 0x0020
751#define IPW_REG_GP_CNTRL IPW_REG_DOMAIN_0_OFFSET + 0x0024
752#define IPW_REG_GPIO IPW_REG_DOMAIN_0_OFFSET + 0x0030
753#define IPW_REG_FW_TYPE IPW_REG_DOMAIN_1_OFFSET + 0x0188
754#define IPW_REG_FW_VERSION IPW_REG_DOMAIN_1_OFFSET + 0x018C
755#define IPW_REG_FW_COMPATABILITY_VERSION IPW_REG_DOMAIN_1_OFFSET + 0x0190
756
757#define IPW_REG_INDIRECT_ADDR_MASK 0x00FFFFFC
758
759#define IPW_INTERRUPT_MASK 0xC1010013
760
761#define IPW2100_CONTROL_REG 0x220000
762#define IPW2100_CONTROL_PHY_OFF 0x8
763
764#define IPW2100_COMMAND 0x00300004
765#define IPW2100_COMMAND_PHY_ON 0x0
766#define IPW2100_COMMAND_PHY_OFF 0x1
767
768/* in DEBUG_AREA, values of memory always 0xd55555d5 */
769#define IPW_REG_DOA_DEBUG_AREA_START IPW_REG_DOMAIN_0_OFFSET + 0x0090
770#define IPW_REG_DOA_DEBUG_AREA_END IPW_REG_DOMAIN_0_OFFSET + 0x00FF
771#define IPW_DATA_DOA_DEBUG_VALUE 0xd55555d5
772
773#define IPW_INTERNAL_REGISTER_HALT_AND_RESET 0x003000e0
774
775#define IPW_WAIT_CLOCK_STABILIZATION_DELAY 50 // micro seconds
776#define IPW_WAIT_RESET_ARC_COMPLETE_DELAY 10 // micro seconds
777#define IPW_WAIT_RESET_MASTER_ASSERT_COMPLETE_DELAY 10 // micro seconds
778
779// BD ring queue read/write difference
780#define IPW_BD_QUEUE_W_R_MIN_SPARE 2
781
782#define IPW_CACHE_LINE_LENGTH_DEFAULT 0x80
783
784#define IPW_CARD_DISABLE_PHY_OFF_COMPLETE_WAIT 100 // 100 milli
785#define IPW_PREPARE_POWER_DOWN_COMPLETE_WAIT 100 // 100 milli
786
787
788
789
790#define IPW_HEADER_802_11_SIZE sizeof(struct ieee80211_hdr_3addr)
791#define IPW_MAX_80211_PAYLOAD_SIZE 2304U
792#define IPW_MAX_802_11_PAYLOAD_LENGTH 2312
793#define IPW_MAX_ACCEPTABLE_TX_FRAME_LENGTH 1536
794#define IPW_MIN_ACCEPTABLE_RX_FRAME_LENGTH 60
795#define IPW_MAX_ACCEPTABLE_RX_FRAME_LENGTH \
796 (IPW_MAX_ACCEPTABLE_TX_FRAME_LENGTH + IPW_HEADER_802_11_SIZE - \
797 sizeof(struct ethhdr))
798
799#define IPW_802_11_FCS_LENGTH 4
800#define IPW_RX_NIC_BUFFER_LENGTH \
801 (IPW_MAX_802_11_PAYLOAD_LENGTH + IPW_HEADER_802_11_SIZE + \
802 IPW_802_11_FCS_LENGTH)
803
804#define IPW_802_11_PAYLOAD_OFFSET \
805 (sizeof(struct ieee80211_hdr_3addr) + \
806 sizeof(struct ieee80211_snap_hdr))
807
808struct ipw2100_rx {
809 union {
810 unsigned char payload[IPW_RX_NIC_BUFFER_LENGTH];
811 struct ieee80211_hdr header;
812 u32 status;
813 struct ipw2100_notification notification;
814 struct ipw2100_cmd_header command;
815 } rx_data;
816} __attribute__ ((packed));
817
818/* Bit 0-7 are for 802.11b tx rates - . Bit 5-7 are reserved */
819#define TX_RATE_1_MBIT 0x0001
820#define TX_RATE_2_MBIT 0x0002
821#define TX_RATE_5_5_MBIT 0x0004
822#define TX_RATE_11_MBIT 0x0008
823#define TX_RATE_MASK 0x000F
824#define DEFAULT_TX_RATES 0x000F
825
826#define IPW_POWER_MODE_CAM 0x00 //(always on)
827#define IPW_POWER_INDEX_1 0x01
828#define IPW_POWER_INDEX_2 0x02
829#define IPW_POWER_INDEX_3 0x03
830#define IPW_POWER_INDEX_4 0x04
831#define IPW_POWER_INDEX_5 0x05
832#define IPW_POWER_AUTO 0x06
833#define IPW_POWER_MASK 0x0F
834#define IPW_POWER_ENABLED 0x10
835#define IPW_POWER_LEVEL(x) ((x) & IPW_POWER_MASK)
836
837#define IPW_TX_POWER_AUTO 0
838#define IPW_TX_POWER_ENHANCED 1
839
840#define IPW_TX_POWER_DEFAULT 32
841#define IPW_TX_POWER_MIN 0
842#define IPW_TX_POWER_MAX 16
843#define IPW_TX_POWER_MIN_DBM (-12)
844#define IPW_TX_POWER_MAX_DBM 16
845
846#define FW_SCAN_DONOT_ASSOCIATE 0x0001 // Dont Attempt to Associate after Scan
847#define FW_SCAN_PASSIVE 0x0008 // Force PASSSIVE Scan
848
849#define REG_MIN_CHANNEL 0
850#define REG_MAX_CHANNEL 14
851
852#define REG_CHANNEL_MASK 0x00003FFF
853#define IPW_IBSS_11B_DEFAULT_MASK 0x87ff
854
855#define DIVERSITY_EITHER 0 // Use both antennas
856#define DIVERSITY_ANTENNA_A 1 // Use antenna A
857#define DIVERSITY_ANTENNA_B 2 // Use antenna B
858
859
860#define HOST_COMMAND_WAIT 0
861#define HOST_COMMAND_NO_WAIT 1
862
863#define LOCK_NONE 0
864#define LOCK_DRIVER 1
865#define LOCK_FW 2
866
867#define TYPE_SWEEP_ORD 0x000D
868#define TYPE_IBSS_STTN_ORD 0x000E
869#define TYPE_BSS_AP_ORD 0x000F
870#define TYPE_RAW_BEACON_ENTRY 0x0010
871#define TYPE_CALIBRATION_DATA 0x0011
872#define TYPE_ROGUE_AP_DATA 0x0012
873#define TYPE_ASSOCIATION_REQUEST 0x0013
874#define TYPE_REASSOCIATION_REQUEST 0x0014
875
876
877#define HW_FEATURE_RFKILL (0x0001)
878#define RF_KILLSWITCH_OFF (1)
879#define RF_KILLSWITCH_ON (0)
880
881#define IPW_COMMAND_POOL_SIZE 40
882
883#define IPW_START_ORD_TAB_1 1
884#define IPW_START_ORD_TAB_2 1000
885
886#define IPW_ORD_TAB_1_ENTRY_SIZE sizeof(u32)
887
888#define IS_ORDINAL_TABLE_ONE(mgr,id) \
889 ((id >= IPW_START_ORD_TAB_1) && (id < mgr->table1_size))
890#define IS_ORDINAL_TABLE_TWO(mgr,id) \
891 ((id >= IPW_START_ORD_TAB_2) && (id < (mgr->table2_size + IPW_START_ORD_TAB_2)))
892
893#define BSS_ID_LENGTH 6
894
895// Fixed size data: Ordinal Table 1
896typedef enum _ORDINAL_TABLE_1 { // NS - means Not Supported by FW
897// Transmit statistics
898 IPW_ORD_STAT_TX_HOST_REQUESTS = 1,// # of requested Host Tx's (MSDU)
899 IPW_ORD_STAT_TX_HOST_COMPLETE, // # of successful Host Tx's (MSDU)
900 IPW_ORD_STAT_TX_DIR_DATA, // # of successful Directed Tx's (MSDU)
901
902 IPW_ORD_STAT_TX_DIR_DATA1 = 4, // # of successful Directed Tx's (MSDU) @ 1MB
903 IPW_ORD_STAT_TX_DIR_DATA2, // # of successful Directed Tx's (MSDU) @ 2MB
904 IPW_ORD_STAT_TX_DIR_DATA5_5, // # of successful Directed Tx's (MSDU) @ 5_5MB
905 IPW_ORD_STAT_TX_DIR_DATA11, // # of successful Directed Tx's (MSDU) @ 11MB
906 IPW_ORD_STAT_TX_DIR_DATA22, // # of successful Directed Tx's (MSDU) @ 22MB
907
908 IPW_ORD_STAT_TX_NODIR_DATA1 = 13,// # of successful Non_Directed Tx's (MSDU) @ 1MB
909 IPW_ORD_STAT_TX_NODIR_DATA2, // # of successful Non_Directed Tx's (MSDU) @ 2MB
910 IPW_ORD_STAT_TX_NODIR_DATA5_5, // # of successful Non_Directed Tx's (MSDU) @ 5.5MB
911 IPW_ORD_STAT_TX_NODIR_DATA11, // # of successful Non_Directed Tx's (MSDU) @ 11MB
912
913 IPW_ORD_STAT_NULL_DATA = 21, // # of successful NULL data Tx's
914 IPW_ORD_STAT_TX_RTS, // # of successful Tx RTS
915 IPW_ORD_STAT_TX_CTS, // # of successful Tx CTS
916 IPW_ORD_STAT_TX_ACK, // # of successful Tx ACK
917 IPW_ORD_STAT_TX_ASSN, // # of successful Association Tx's
918 IPW_ORD_STAT_TX_ASSN_RESP, // # of successful Association response Tx's
919 IPW_ORD_STAT_TX_REASSN, // # of successful Reassociation Tx's
920 IPW_ORD_STAT_TX_REASSN_RESP, // # of successful Reassociation response Tx's
921 IPW_ORD_STAT_TX_PROBE, // # of probes successfully transmitted
922 IPW_ORD_STAT_TX_PROBE_RESP, // # of probe responses successfully transmitted
923 IPW_ORD_STAT_TX_BEACON, // # of tx beacon
924 IPW_ORD_STAT_TX_ATIM, // # of Tx ATIM
925 IPW_ORD_STAT_TX_DISASSN, // # of successful Disassociation TX
926 IPW_ORD_STAT_TX_AUTH, // # of successful Authentication Tx
927 IPW_ORD_STAT_TX_DEAUTH, // # of successful Deauthentication TX
928
929 IPW_ORD_STAT_TX_TOTAL_BYTES = 41,// Total successful Tx data bytes
930 IPW_ORD_STAT_TX_RETRIES, // # of Tx retries
931 IPW_ORD_STAT_TX_RETRY1, // # of Tx retries at 1MBPS
932 IPW_ORD_STAT_TX_RETRY2, // # of Tx retries at 2MBPS
933 IPW_ORD_STAT_TX_RETRY5_5, // # of Tx retries at 5.5MBPS
934 IPW_ORD_STAT_TX_RETRY11, // # of Tx retries at 11MBPS
935
936 IPW_ORD_STAT_TX_FAILURES = 51, // # of Tx Failures
937 IPW_ORD_STAT_TX_ABORT_AT_HOP, //NS // # of Tx's aborted at hop time
938 IPW_ORD_STAT_TX_MAX_TRIES_IN_HOP,// # of times max tries in a hop failed
939 IPW_ORD_STAT_TX_ABORT_LATE_DMA, //NS // # of times tx aborted due to late dma setup
940 IPW_ORD_STAT_TX_ABORT_STX, //NS // # of times backoff aborted
941 IPW_ORD_STAT_TX_DISASSN_FAIL, // # of times disassociation failed
942 IPW_ORD_STAT_TX_ERR_CTS, // # of missed/bad CTS frames
943 IPW_ORD_STAT_TX_BPDU, //NS // # of spanning tree BPDUs sent
944 IPW_ORD_STAT_TX_ERR_ACK, // # of tx err due to acks
945
946 // Receive statistics
947 IPW_ORD_STAT_RX_HOST = 61, // # of packets passed to host
948 IPW_ORD_STAT_RX_DIR_DATA, // # of directed packets
949 IPW_ORD_STAT_RX_DIR_DATA1, // # of directed packets at 1MB
950 IPW_ORD_STAT_RX_DIR_DATA2, // # of directed packets at 2MB
951 IPW_ORD_STAT_RX_DIR_DATA5_5, // # of directed packets at 5.5MB
952 IPW_ORD_STAT_RX_DIR_DATA11, // # of directed packets at 11MB
953 IPW_ORD_STAT_RX_DIR_DATA22, // # of directed packets at 22MB
954
955 IPW_ORD_STAT_RX_NODIR_DATA = 71,// # of nondirected packets
956 IPW_ORD_STAT_RX_NODIR_DATA1, // # of nondirected packets at 1MB
957 IPW_ORD_STAT_RX_NODIR_DATA2, // # of nondirected packets at 2MB
958 IPW_ORD_STAT_RX_NODIR_DATA5_5, // # of nondirected packets at 5.5MB
959 IPW_ORD_STAT_RX_NODIR_DATA11, // # of nondirected packets at 11MB
960
961 IPW_ORD_STAT_RX_NULL_DATA = 80, // # of null data rx's
962 IPW_ORD_STAT_RX_POLL, //NS // # of poll rx
963 IPW_ORD_STAT_RX_RTS, // # of Rx RTS
964 IPW_ORD_STAT_RX_CTS, // # of Rx CTS
965 IPW_ORD_STAT_RX_ACK, // # of Rx ACK
966 IPW_ORD_STAT_RX_CFEND, // # of Rx CF End
967 IPW_ORD_STAT_RX_CFEND_ACK, // # of Rx CF End + CF Ack
968 IPW_ORD_STAT_RX_ASSN, // # of Association Rx's
969 IPW_ORD_STAT_RX_ASSN_RESP, // # of Association response Rx's
970 IPW_ORD_STAT_RX_REASSN, // # of Reassociation Rx's
971 IPW_ORD_STAT_RX_REASSN_RESP, // # of Reassociation response Rx's
972 IPW_ORD_STAT_RX_PROBE, // # of probe Rx's
973 IPW_ORD_STAT_RX_PROBE_RESP, // # of probe response Rx's
974 IPW_ORD_STAT_RX_BEACON, // # of Rx beacon
975 IPW_ORD_STAT_RX_ATIM, // # of Rx ATIM
976 IPW_ORD_STAT_RX_DISASSN, // # of disassociation Rx
977 IPW_ORD_STAT_RX_AUTH, // # of authentication Rx
978 IPW_ORD_STAT_RX_DEAUTH, // # of deauthentication Rx
979
980 IPW_ORD_STAT_RX_TOTAL_BYTES = 101,// Total rx data bytes received
981 IPW_ORD_STAT_RX_ERR_CRC, // # of packets with Rx CRC error
982 IPW_ORD_STAT_RX_ERR_CRC1, // # of Rx CRC errors at 1MB
983 IPW_ORD_STAT_RX_ERR_CRC2, // # of Rx CRC errors at 2MB
984 IPW_ORD_STAT_RX_ERR_CRC5_5, // # of Rx CRC errors at 5.5MB
985 IPW_ORD_STAT_RX_ERR_CRC11, // # of Rx CRC errors at 11MB
986
987 IPW_ORD_STAT_RX_DUPLICATE1 = 112, // # of duplicate rx packets at 1MB
988 IPW_ORD_STAT_RX_DUPLICATE2, // # of duplicate rx packets at 2MB
989 IPW_ORD_STAT_RX_DUPLICATE5_5, // # of duplicate rx packets at 5.5MB
990 IPW_ORD_STAT_RX_DUPLICATE11, // # of duplicate rx packets at 11MB
991 IPW_ORD_STAT_RX_DUPLICATE = 119, // # of duplicate rx packets
992
993 IPW_ORD_PERS_DB_LOCK = 120, // # locking fw permanent db
994 IPW_ORD_PERS_DB_SIZE, // # size of fw permanent db
995 IPW_ORD_PERS_DB_ADDR, // # address of fw permanent db
996 IPW_ORD_STAT_RX_INVALID_PROTOCOL, // # of rx frames with invalid protocol
997 IPW_ORD_SYS_BOOT_TIME, // # Boot time
998 IPW_ORD_STAT_RX_NO_BUFFER, // # of rx frames rejected due to no buffer
999 IPW_ORD_STAT_RX_ABORT_LATE_DMA, //NS // # of rx frames rejected due to dma setup too late
1000 IPW_ORD_STAT_RX_ABORT_AT_HOP, //NS // # of rx frames aborted due to hop
1001 IPW_ORD_STAT_RX_MISSING_FRAG, // # of rx frames dropped due to missing fragment
1002 IPW_ORD_STAT_RX_ORPHAN_FRAG, // # of rx frames dropped due to non-sequential fragment
1003 IPW_ORD_STAT_RX_ORPHAN_FRAME, // # of rx frames dropped due to unmatched 1st frame
1004 IPW_ORD_STAT_RX_FRAG_AGEOUT, // # of rx frames dropped due to uncompleted frame
1005 IPW_ORD_STAT_RX_BAD_SSID, //NS // Bad SSID (unused)
1006 IPW_ORD_STAT_RX_ICV_ERRORS, // # of ICV errors during decryption
1007
1008// PSP Statistics
1009 IPW_ORD_STAT_PSP_SUSPENSION = 137,// # of times adapter suspended
1010 IPW_ORD_STAT_PSP_BCN_TIMEOUT, // # of beacon timeout
1011 IPW_ORD_STAT_PSP_POLL_TIMEOUT, // # of poll response timeouts
1012 IPW_ORD_STAT_PSP_NONDIR_TIMEOUT,// # of timeouts waiting for last broadcast/muticast pkt
1013 IPW_ORD_STAT_PSP_RX_DTIMS, // # of PSP DTIMs received
1014 IPW_ORD_STAT_PSP_RX_TIMS, // # of PSP TIMs received
1015 IPW_ORD_STAT_PSP_STATION_ID, // PSP Station ID
1016
1017// Association and roaming
1018 IPW_ORD_LAST_ASSN_TIME = 147, // RTC time of last association
1019 IPW_ORD_STAT_PERCENT_MISSED_BCNS,// current calculation of % missed beacons
1020 IPW_ORD_STAT_PERCENT_RETRIES, // current calculation of % missed tx retries
1021 IPW_ORD_ASSOCIATED_AP_PTR, // If associated, this is ptr to the associated
1022 // AP table entry. set to 0 if not associated
1023 IPW_ORD_AVAILABLE_AP_CNT, // # of AP's decsribed in the AP table
1024 IPW_ORD_AP_LIST_PTR, // Ptr to list of available APs
1025 IPW_ORD_STAT_AP_ASSNS, // # of associations
1026 IPW_ORD_STAT_ASSN_FAIL, // # of association failures
1027 IPW_ORD_STAT_ASSN_RESP_FAIL, // # of failuresdue to response fail
1028 IPW_ORD_STAT_FULL_SCANS, // # of full scans
1029
1030 IPW_ORD_CARD_DISABLED, // # Card Disabled
1031 IPW_ORD_STAT_ROAM_INHIBIT, // # of times roaming was inhibited due to ongoing activity
1032 IPW_FILLER_40,
1033 IPW_ORD_RSSI_AT_ASSN = 160, // RSSI of associated AP at time of association
1034 IPW_ORD_STAT_ASSN_CAUSE1, // # of reassociations due to no tx from AP in last N
1035 // hops or no prob_ responses in last 3 minutes
1036 IPW_ORD_STAT_ASSN_CAUSE2, // # of reassociations due to poor tx/rx quality
1037 IPW_ORD_STAT_ASSN_CAUSE3, // # of reassociations due to tx/rx quality with excessive
1038 // load at the AP
1039 IPW_ORD_STAT_ASSN_CAUSE4, // # of reassociations due to AP RSSI level fell below
1040 // eligible group
1041 IPW_ORD_STAT_ASSN_CAUSE5, // # of reassociations due to load leveling
1042 IPW_ORD_STAT_ASSN_CAUSE6, //NS // # of reassociations due to dropped by Ap
1043 IPW_FILLER_41,
1044 IPW_FILLER_42,
1045 IPW_FILLER_43,
1046 IPW_ORD_STAT_AUTH_FAIL, // # of times authentication failed
1047 IPW_ORD_STAT_AUTH_RESP_FAIL, // # of times authentication response failed
1048 IPW_ORD_STATION_TABLE_CNT, // # of entries in association table
1049
1050// Other statistics
1051 IPW_ORD_RSSI_AVG_CURR = 173, // Current avg RSSI
1052 IPW_ORD_STEST_RESULTS_CURR, //NS // Current self test results word
1053 IPW_ORD_STEST_RESULTS_CUM, //NS // Cummulative self test results word
1054 IPW_ORD_SELF_TEST_STATUS, //NS //
1055 IPW_ORD_POWER_MGMT_MODE, // Power mode - 0=CAM, 1=PSP
1056 IPW_ORD_POWER_MGMT_INDEX, //NS //
1057 IPW_ORD_COUNTRY_CODE, // IEEE country code as recv'd from beacon
1058 IPW_ORD_COUNTRY_CHANNELS, // channels suported by country
1059// IPW_ORD_COUNTRY_CHANNELS:
1060// For 11b the lower 2-byte are used for channels from 1-14
1061// and the higher 2-byte are not used.
1062 IPW_ORD_RESET_CNT, // # of adapter resets (warm)
1063 IPW_ORD_BEACON_INTERVAL, // Beacon interval
1064
1065 IPW_ORD_PRINCETON_VERSION = 184, //NS // Princeton Version
1066 IPW_ORD_ANTENNA_DIVERSITY, // TRUE if antenna diversity is disabled
1067 IPW_ORD_CCA_RSSI, //NS // CCA RSSI value (factory programmed)
1068 IPW_ORD_STAT_EEPROM_UPDATE, //NS // # of times config EEPROM updated
1069 IPW_ORD_DTIM_PERIOD, // # of beacon intervals between DTIMs
1070 IPW_ORD_OUR_FREQ, // current radio freq lower digits - channel ID
1071
1072 IPW_ORD_RTC_TIME = 190, // current RTC time
1073 IPW_ORD_PORT_TYPE, // operating mode
1074 IPW_ORD_CURRENT_TX_RATE, // current tx rate
1075 IPW_ORD_SUPPORTED_RATES, // Bitmap of supported tx rates
1076 IPW_ORD_ATIM_WINDOW, // current ATIM Window
1077 IPW_ORD_BASIC_RATES, // bitmap of basic tx rates
1078 IPW_ORD_NIC_HIGHEST_RATE, // bitmap of basic tx rates
1079 IPW_ORD_AP_HIGHEST_RATE, // bitmap of basic tx rates
1080 IPW_ORD_CAPABILITIES, // Management frame capability field
1081 IPW_ORD_AUTH_TYPE, // Type of authentication
1082 IPW_ORD_RADIO_TYPE, // Adapter card platform type
1083 IPW_ORD_RTS_THRESHOLD = 201, // Min length of packet after which RTS handshaking is used
1084 IPW_ORD_INT_MODE, // International mode
1085 IPW_ORD_FRAGMENTATION_THRESHOLD, // protocol frag threshold
1086 IPW_ORD_EEPROM_SRAM_DB_BLOCK_START_ADDRESS, // EEPROM offset in SRAM
1087 IPW_ORD_EEPROM_SRAM_DB_BLOCK_SIZE, // EEPROM size in SRAM
1088 IPW_ORD_EEPROM_SKU_CAPABILITY, // EEPROM SKU Capability 206 =
1089 IPW_ORD_EEPROM_IBSS_11B_CHANNELS, // EEPROM IBSS 11b channel set
1090
1091 IPW_ORD_MAC_VERSION = 209, // MAC Version
1092 IPW_ORD_MAC_REVISION, // MAC Revision
1093 IPW_ORD_RADIO_VERSION, // Radio Version
1094 IPW_ORD_NIC_MANF_DATE_TIME, // MANF Date/Time STAMP
1095 IPW_ORD_UCODE_VERSION, // Ucode Version
1096 IPW_ORD_HW_RF_SWITCH_STATE = 214, // HW RF Kill Switch State
1097} ORDINALTABLE1;
1098
1099// ordinal table 2
1100// Variable length data:
1101#define IPW_FIRST_VARIABLE_LENGTH_ORDINAL 1001
1102
1103typedef enum _ORDINAL_TABLE_2 { // NS - means Not Supported by FW
1104 IPW_ORD_STAT_BASE = 1000, // contains number of variable ORDs
1105 IPW_ORD_STAT_ADAPTER_MAC = 1001, // 6 bytes: our adapter MAC address
1106 IPW_ORD_STAT_PREFERRED_BSSID = 1002, // 6 bytes: BSSID of the preferred AP
1107 IPW_ORD_STAT_MANDATORY_BSSID = 1003, // 6 bytes: BSSID of the mandatory AP
1108 IPW_FILL_1, //NS //
1109 IPW_ORD_STAT_COUNTRY_TEXT = 1005, // 36 bytes: Country name text, First two bytes are Country code
1110 IPW_ORD_STAT_ASSN_SSID = 1006, // 32 bytes: ESSID String
1111 IPW_ORD_STATION_TABLE = 1007, // ? bytes: Station/AP table (via Direct SSID Scans)
1112 IPW_ORD_STAT_SWEEP_TABLE = 1008, // ? bytes: Sweep/Host Table table (via Broadcast Scans)
1113 IPW_ORD_STAT_ROAM_LOG = 1009, // ? bytes: Roaming log
1114 IPW_ORD_STAT_RATE_LOG = 1010, //NS // 0 bytes: Rate log
1115 IPW_ORD_STAT_FIFO = 1011, //NS // 0 bytes: Fifo buffer data structures
1116 IPW_ORD_STAT_FW_VER_NUM = 1012, // 14 bytes: fw version ID string as in (a.bb.ccc; "0.08.011")
1117 IPW_ORD_STAT_FW_DATE = 1013, // 14 bytes: fw date string (mmm dd yyyy; "Mar 13 2002")
1118 IPW_ORD_STAT_ASSN_AP_BSSID = 1014, // 6 bytes: MAC address of associated AP
1119 IPW_ORD_STAT_DEBUG = 1015, //NS // ? bytes:
1120 IPW_ORD_STAT_NIC_BPA_NUM = 1016, // 11 bytes: NIC BPA number in ASCII
1121 IPW_ORD_STAT_UCODE_DATE = 1017, // 5 bytes: uCode date
1122 IPW_ORD_SECURITY_NGOTIATION_RESULT = 1018,
1123} ORDINALTABLE2; // NS - means Not Supported by FW
1124
1125#define IPW_LAST_VARIABLE_LENGTH_ORDINAL 1018
1126
1127#ifndef WIRELESS_SPY
1128#define WIRELESS_SPY // enable iwspy support
1129#endif
1130
1131#define IPW_HOST_FW_SHARED_AREA0 0x0002f200
1132#define IPW_HOST_FW_SHARED_AREA0_END 0x0002f510 // 0x310 bytes
1133
1134#define IPW_HOST_FW_SHARED_AREA1 0x0002f610
1135#define IPW_HOST_FW_SHARED_AREA1_END 0x0002f630 // 0x20 bytes
1136
1137#define IPW_HOST_FW_SHARED_AREA2 0x0002fa00
1138#define IPW_HOST_FW_SHARED_AREA2_END 0x0002fa20 // 0x20 bytes
1139
1140#define IPW_HOST_FW_SHARED_AREA3 0x0002fc00
1141#define IPW_HOST_FW_SHARED_AREA3_END 0x0002fc10 // 0x10 bytes
1142
1143#define IPW_HOST_FW_INTERRUPT_AREA 0x0002ff80
1144#define IPW_HOST_FW_INTERRUPT_AREA_END 0x00030000 // 0x80 bytes
1145
1146struct ipw2100_fw_chunk {
1147 unsigned char *buf;
1148 long len;
1149 long pos;
1150 struct list_head list;
1151};
1152
1153struct ipw2100_fw_chunk_set {
1154 const void *data;
1155 unsigned long size;
1156};
1157
1158struct ipw2100_fw {
1159 int version;
1160 struct ipw2100_fw_chunk_set fw;
1161 struct ipw2100_fw_chunk_set uc;
1162 const struct firmware *fw_entry;
1163};
1164
1165#define MAX_FW_VERSION_LEN 14
1166
1167#endif /* _IPW2100_H */
diff --git a/drivers/net/wireless/ipw2200.c b/drivers/net/wireless/ipw2200.c
new file mode 100644
index 000000000000..6d0b6b1df4ca
--- /dev/null
+++ b/drivers/net/wireless/ipw2200.c
@@ -0,0 +1,7353 @@
1/******************************************************************************
2
3 Copyright(c) 2003 - 2004 Intel Corporation. All rights reserved.
4
5 802.11 status code portion of this file from ethereal-0.10.6:
6 Copyright 2000, Axis Communications AB
7 Ethereal - Network traffic analyzer
8 By Gerald Combs <gerald@ethereal.com>
9 Copyright 1998 Gerald Combs
10
11 This program is free software; you can redistribute it and/or modify it
12 under the terms of version 2 of the GNU General Public License as
13 published by the Free Software Foundation.
14
15 This program is distributed in the hope that it will be useful, but WITHOUT
16 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
17 FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
18 more details.
19
20 You should have received a copy of the GNU General Public License along with
21 this program; if not, write to the Free Software Foundation, Inc., 59
22 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
23
24 The full GNU General Public License is included in this distribution in the
25 file called LICENSE.
26
27 Contact Information:
28 James P. Ketrenos <ipw2100-admin@linux.intel.com>
29 Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497
30
31******************************************************************************/
32
33#include "ipw2200.h"
34
35#define IPW2200_VERSION "1.0.0"
36#define DRV_DESCRIPTION "Intel(R) PRO/Wireless 2200/2915 Network Driver"
37#define DRV_COPYRIGHT "Copyright(c) 2003-2004 Intel Corporation"
38#define DRV_VERSION IPW2200_VERSION
39
40MODULE_DESCRIPTION(DRV_DESCRIPTION);
41MODULE_VERSION(DRV_VERSION);
42MODULE_AUTHOR(DRV_COPYRIGHT);
43MODULE_LICENSE("GPL");
44
45static int debug = 0;
46static int channel = 0;
47static char *ifname;
48static int mode = 0;
49
50static u32 ipw_debug_level;
51static int associate = 1;
52static int auto_create = 1;
53static int disable = 0;
54static const char ipw_modes[] = {
55 'a', 'b', 'g', '?'
56};
57
58static void ipw_rx(struct ipw_priv *priv);
59static int ipw_queue_tx_reclaim(struct ipw_priv *priv,
60 struct clx2_tx_queue *txq, int qindex);
61static int ipw_queue_reset(struct ipw_priv *priv);
62
63static int ipw_queue_tx_hcmd(struct ipw_priv *priv, int hcmd, void *buf,
64 int len, int sync);
65
66static void ipw_tx_queue_free(struct ipw_priv *);
67
68static struct ipw_rx_queue *ipw_rx_queue_alloc(struct ipw_priv *);
69static void ipw_rx_queue_free(struct ipw_priv *, struct ipw_rx_queue *);
70static void ipw_rx_queue_replenish(void *);
71
72static int ipw_up(struct ipw_priv *);
73static void ipw_down(struct ipw_priv *);
74static int ipw_config(struct ipw_priv *);
75static int init_supported_rates(struct ipw_priv *priv, struct ipw_supported_rates *prates);
76
77static u8 band_b_active_channel[MAX_B_CHANNELS] = {
78 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 0
79};
80static u8 band_a_active_channel[MAX_A_CHANNELS] = {
81 36, 40, 44, 48, 149, 153, 157, 161, 165, 52, 56, 60, 64, 0
82};
83
84static int is_valid_channel(int mode_mask, int channel)
85{
86 int i;
87
88 if (!channel)
89 return 0;
90
91 if (mode_mask & IEEE_A)
92 for (i = 0; i < MAX_A_CHANNELS; i++)
93 if (band_a_active_channel[i] == channel)
94 return IEEE_A;
95
96 if (mode_mask & (IEEE_B | IEEE_G))
97 for (i = 0; i < MAX_B_CHANNELS; i++)
98 if (band_b_active_channel[i] == channel)
99 return mode_mask & (IEEE_B | IEEE_G);
100
101 return 0;
102}
103
104static char *snprint_line(char *buf, size_t count,
105 const u8 *data, u32 len, u32 ofs)
106{
107 int out, i, j, l;
108 char c;
109
110 out = snprintf(buf, count, "%08X", ofs);
111
112 for (l = 0, i = 0; i < 2; i++) {
113 out += snprintf(buf + out, count - out, " ");
114 for (j = 0; j < 8 && l < len; j++, l++)
115 out += snprintf(buf + out, count - out, "%02X ",
116 data[(i * 8 + j)]);
117 for (; j < 8; j++)
118 out += snprintf(buf + out, count - out, " ");
119 }
120
121 out += snprintf(buf + out, count - out, " ");
122 for (l = 0, i = 0; i < 2; i++) {
123 out += snprintf(buf + out, count - out, " ");
124 for (j = 0; j < 8 && l < len; j++, l++) {
125 c = data[(i * 8 + j)];
126 if (!isascii(c) || !isprint(c))
127 c = '.';
128
129 out += snprintf(buf + out, count - out, "%c", c);
130 }
131
132 for (; j < 8; j++)
133 out += snprintf(buf + out, count - out, " ");
134 }
135
136 return buf;
137}
138
139static void printk_buf(int level, const u8 *data, u32 len)
140{
141 char line[81];
142 u32 ofs = 0;
143 if (!(ipw_debug_level & level))
144 return;
145
146 while (len) {
147 printk(KERN_DEBUG "%s\n",
148 snprint_line(line, sizeof(line), &data[ofs],
149 min(len, 16U), ofs));
150 ofs += 16;
151 len -= min(len, 16U);
152 }
153}
154
155static u32 _ipw_read_reg32(struct ipw_priv *priv, u32 reg);
156#define ipw_read_reg32(a, b) _ipw_read_reg32(a, b)
157
158static u8 _ipw_read_reg8(struct ipw_priv *ipw, u32 reg);
159#define ipw_read_reg8(a, b) _ipw_read_reg8(a, b)
160
161static void _ipw_write_reg8(struct ipw_priv *priv, u32 reg, u8 value);
162static inline void ipw_write_reg8(struct ipw_priv *a, u32 b, u8 c)
163{
164 IPW_DEBUG_IO("%s %d: write_indirect8(0x%08X, 0x%08X)\n", __FILE__, __LINE__, (u32)(b), (u32)(c));
165 _ipw_write_reg8(a, b, c);
166}
167
168static void _ipw_write_reg16(struct ipw_priv *priv, u32 reg, u16 value);
169static inline void ipw_write_reg16(struct ipw_priv *a, u32 b, u16 c)
170{
171 IPW_DEBUG_IO("%s %d: write_indirect16(0x%08X, 0x%08X)\n", __FILE__, __LINE__, (u32)(b), (u32)(c));
172 _ipw_write_reg16(a, b, c);
173}
174
175static void _ipw_write_reg32(struct ipw_priv *priv, u32 reg, u32 value);
176static inline void ipw_write_reg32(struct ipw_priv *a, u32 b, u32 c)
177{
178 IPW_DEBUG_IO("%s %d: write_indirect32(0x%08X, 0x%08X)\n", __FILE__, __LINE__, (u32)(b), (u32)(c));
179 _ipw_write_reg32(a, b, c);
180}
181
182#define _ipw_write8(ipw, ofs, val) writeb((val), (ipw)->hw_base + (ofs))
183#define ipw_write8(ipw, ofs, val) \
184 IPW_DEBUG_IO("%s %d: write_direct8(0x%08X, 0x%08X)\n", __FILE__, __LINE__, (u32)(ofs), (u32)(val)); \
185 _ipw_write8(ipw, ofs, val)
186
187#define _ipw_write16(ipw, ofs, val) writew((val), (ipw)->hw_base + (ofs))
188#define ipw_write16(ipw, ofs, val) \
189 IPW_DEBUG_IO("%s %d: write_direct16(0x%08X, 0x%08X)\n", __FILE__, __LINE__, (u32)(ofs), (u32)(val)); \
190 _ipw_write16(ipw, ofs, val)
191
192#define _ipw_write32(ipw, ofs, val) writel((val), (ipw)->hw_base + (ofs))
193#define ipw_write32(ipw, ofs, val) \
194 IPW_DEBUG_IO("%s %d: write_direct32(0x%08X, 0x%08X)\n", __FILE__, __LINE__, (u32)(ofs), (u32)(val)); \
195 _ipw_write32(ipw, ofs, val)
196
197#define _ipw_read8(ipw, ofs) readb((ipw)->hw_base + (ofs))
198static inline u8 __ipw_read8(char *f, u32 l, struct ipw_priv *ipw, u32 ofs) {
199 IPW_DEBUG_IO("%s %d: read_direct8(0x%08X)\n", f, l, (u32)(ofs));
200 return _ipw_read8(ipw, ofs);
201}
202#define ipw_read8(ipw, ofs) __ipw_read8(__FILE__, __LINE__, ipw, ofs)
203
204#define _ipw_read16(ipw, ofs) readw((ipw)->hw_base + (ofs))
205static inline u16 __ipw_read16(char *f, u32 l, struct ipw_priv *ipw, u32 ofs) {
206 IPW_DEBUG_IO("%s %d: read_direct16(0x%08X)\n", f, l, (u32)(ofs));
207 return _ipw_read16(ipw, ofs);
208}
209#define ipw_read16(ipw, ofs) __ipw_read16(__FILE__, __LINE__, ipw, ofs)
210
211#define _ipw_read32(ipw, ofs) readl((ipw)->hw_base + (ofs))
212static inline u32 __ipw_read32(char *f, u32 l, struct ipw_priv *ipw, u32 ofs) {
213 IPW_DEBUG_IO("%s %d: read_direct32(0x%08X)\n", f, l, (u32)(ofs));
214 return _ipw_read32(ipw, ofs);
215}
216#define ipw_read32(ipw, ofs) __ipw_read32(__FILE__, __LINE__, ipw, ofs)
217
218static void _ipw_read_indirect(struct ipw_priv *, u32, u8 *, int);
219#define ipw_read_indirect(a, b, c, d) \
220 IPW_DEBUG_IO("%s %d: read_inddirect(0x%08X) %d bytes\n", __FILE__, __LINE__, (u32)(b), d); \
221 _ipw_read_indirect(a, b, c, d)
222
223static void _ipw_write_indirect(struct ipw_priv *priv, u32 addr, u8 *data, int num);
224#define ipw_write_indirect(a, b, c, d) \
225 IPW_DEBUG_IO("%s %d: write_indirect(0x%08X) %d bytes\n", __FILE__, __LINE__, (u32)(b), d); \
226 _ipw_write_indirect(a, b, c, d)
227
228/* indirect write s */
229static void _ipw_write_reg32(struct ipw_priv *priv, u32 reg,
230 u32 value)
231{
232 IPW_DEBUG_IO(" %p : reg = 0x%8X : value = 0x%8X\n",
233 priv, reg, value);
234 _ipw_write32(priv, CX2_INDIRECT_ADDR, reg);
235 _ipw_write32(priv, CX2_INDIRECT_DATA, value);
236}
237
238
239static void _ipw_write_reg8(struct ipw_priv *priv, u32 reg, u8 value)
240{
241 IPW_DEBUG_IO(" reg = 0x%8X : value = 0x%8X\n", reg, value);
242 _ipw_write32(priv, CX2_INDIRECT_ADDR, reg & CX2_INDIRECT_ADDR_MASK);
243 _ipw_write8(priv, CX2_INDIRECT_DATA, value);
244 IPW_DEBUG_IO(" reg = 0x%8lX : value = 0x%8X\n",
245 (unsigned long)(priv->hw_base + CX2_INDIRECT_DATA),
246 value);
247}
248
249static void _ipw_write_reg16(struct ipw_priv *priv, u32 reg,
250 u16 value)
251{
252 IPW_DEBUG_IO(" reg = 0x%8X : value = 0x%8X\n", reg, value);
253 _ipw_write32(priv, CX2_INDIRECT_ADDR, reg & CX2_INDIRECT_ADDR_MASK);
254 _ipw_write16(priv, CX2_INDIRECT_DATA, value);
255}
256
257/* indirect read s */
258
259static u8 _ipw_read_reg8(struct ipw_priv *priv, u32 reg)
260{
261 u32 word;
262 _ipw_write32(priv, CX2_INDIRECT_ADDR, reg & CX2_INDIRECT_ADDR_MASK);
263 IPW_DEBUG_IO(" reg = 0x%8X : \n", reg);
264 word = _ipw_read32(priv, CX2_INDIRECT_DATA);
265 return (word >> ((reg & 0x3)*8)) & 0xff;
266}
267
268static u32 _ipw_read_reg32(struct ipw_priv *priv, u32 reg)
269{
270 u32 value;
271
272 IPW_DEBUG_IO("%p : reg = 0x%08x\n", priv, reg);
273
274 _ipw_write32(priv, CX2_INDIRECT_ADDR, reg);
275 value = _ipw_read32(priv, CX2_INDIRECT_DATA);
276 IPW_DEBUG_IO(" reg = 0x%4X : value = 0x%4x \n", reg, value);
277 return value;
278}
279
280/* iterative/auto-increment 32 bit reads and writes */
281static void _ipw_read_indirect(struct ipw_priv *priv, u32 addr, u8 * buf,
282 int num)
283{
284 u32 aligned_addr = addr & CX2_INDIRECT_ADDR_MASK;
285 u32 dif_len = addr - aligned_addr;
286 u32 aligned_len;
287 u32 i;
288
289 IPW_DEBUG_IO("addr = %i, buf = %p, num = %i\n", addr, buf, num);
290
291 /* Read the first nibble byte by byte */
292 if (unlikely(dif_len)) {
293 /* Start reading at aligned_addr + dif_len */
294 _ipw_write32(priv, CX2_INDIRECT_ADDR, aligned_addr);
295 for (i = dif_len; i < 4; i++, buf++)
296 *buf = _ipw_read8(priv, CX2_INDIRECT_DATA + i);
297 num -= dif_len;
298 aligned_addr += 4;
299 }
300
301 /* Read DWs through autoinc register */
302 _ipw_write32(priv, CX2_AUTOINC_ADDR, aligned_addr);
303 aligned_len = num & CX2_INDIRECT_ADDR_MASK;
304 for (i = 0; i < aligned_len; i += 4, buf += 4, aligned_addr += 4)
305 *(u32*)buf = ipw_read32(priv, CX2_AUTOINC_DATA);
306
307 /* Copy the last nibble */
308 dif_len = num - aligned_len;
309 _ipw_write32(priv, CX2_INDIRECT_ADDR, aligned_addr);
310 for (i = 0; i < dif_len; i++, buf++)
311 *buf = ipw_read8(priv, CX2_INDIRECT_DATA + i);
312}
313
314static void _ipw_write_indirect(struct ipw_priv *priv, u32 addr, u8 *buf,
315 int num)
316{
317 u32 aligned_addr = addr & CX2_INDIRECT_ADDR_MASK;
318 u32 dif_len = addr - aligned_addr;
319 u32 aligned_len;
320 u32 i;
321
322 IPW_DEBUG_IO("addr = %i, buf = %p, num = %i\n", addr, buf, num);
323
324 /* Write the first nibble byte by byte */
325 if (unlikely(dif_len)) {
326 /* Start writing at aligned_addr + dif_len */
327 _ipw_write32(priv, CX2_INDIRECT_ADDR, aligned_addr);
328 for (i = dif_len; i < 4; i++, buf++)
329 _ipw_write8(priv, CX2_INDIRECT_DATA + i, *buf);
330 num -= dif_len;
331 aligned_addr += 4;
332 }
333
334 /* Write DWs through autoinc register */
335 _ipw_write32(priv, CX2_AUTOINC_ADDR, aligned_addr);
336 aligned_len = num & CX2_INDIRECT_ADDR_MASK;
337 for (i = 0; i < aligned_len; i += 4, buf += 4, aligned_addr += 4)
338 _ipw_write32(priv, CX2_AUTOINC_DATA, *(u32*)buf);
339
340 /* Copy the last nibble */
341 dif_len = num - aligned_len;
342 _ipw_write32(priv, CX2_INDIRECT_ADDR, aligned_addr);
343 for (i = 0; i < dif_len; i++, buf++)
344 _ipw_write8(priv, CX2_INDIRECT_DATA + i, *buf);
345}
346
347static void ipw_write_direct(struct ipw_priv *priv, u32 addr, void *buf,
348 int num)
349{
350 memcpy_toio((priv->hw_base + addr), buf, num);
351}
352
353static inline void ipw_set_bit(struct ipw_priv *priv, u32 reg, u32 mask)
354{
355 ipw_write32(priv, reg, ipw_read32(priv, reg) | mask);
356}
357
358static inline void ipw_clear_bit(struct ipw_priv *priv, u32 reg, u32 mask)
359{
360 ipw_write32(priv, reg, ipw_read32(priv, reg) & ~mask);
361}
362
363static inline void ipw_enable_interrupts(struct ipw_priv *priv)
364{
365 if (priv->status & STATUS_INT_ENABLED)
366 return;
367 priv->status |= STATUS_INT_ENABLED;
368 ipw_write32(priv, CX2_INTA_MASK_R, CX2_INTA_MASK_ALL);
369}
370
371static inline void ipw_disable_interrupts(struct ipw_priv *priv)
372{
373 if (!(priv->status & STATUS_INT_ENABLED))
374 return;
375 priv->status &= ~STATUS_INT_ENABLED;
376 ipw_write32(priv, CX2_INTA_MASK_R, ~CX2_INTA_MASK_ALL);
377}
378
379static char *ipw_error_desc(u32 val)
380{
381 switch (val) {
382 case IPW_FW_ERROR_OK:
383 return "ERROR_OK";
384 case IPW_FW_ERROR_FAIL:
385 return "ERROR_FAIL";
386 case IPW_FW_ERROR_MEMORY_UNDERFLOW:
387 return "MEMORY_UNDERFLOW";
388 case IPW_FW_ERROR_MEMORY_OVERFLOW:
389 return "MEMORY_OVERFLOW";
390 case IPW_FW_ERROR_BAD_PARAM:
391 return "ERROR_BAD_PARAM";
392 case IPW_FW_ERROR_BAD_CHECKSUM:
393 return "ERROR_BAD_CHECKSUM";
394 case IPW_FW_ERROR_NMI_INTERRUPT:
395 return "ERROR_NMI_INTERRUPT";
396 case IPW_FW_ERROR_BAD_DATABASE:
397 return "ERROR_BAD_DATABASE";
398 case IPW_FW_ERROR_ALLOC_FAIL:
399 return "ERROR_ALLOC_FAIL";
400 case IPW_FW_ERROR_DMA_UNDERRUN:
401 return "ERROR_DMA_UNDERRUN";
402 case IPW_FW_ERROR_DMA_STATUS:
403 return "ERROR_DMA_STATUS";
404 case IPW_FW_ERROR_DINOSTATUS_ERROR:
405 return "ERROR_DINOSTATUS_ERROR";
406 case IPW_FW_ERROR_EEPROMSTATUS_ERROR:
407 return "ERROR_EEPROMSTATUS_ERROR";
408 case IPW_FW_ERROR_SYSASSERT:
409 return "ERROR_SYSASSERT";
410 case IPW_FW_ERROR_FATAL_ERROR:
411 return "ERROR_FATALSTATUS_ERROR";
412 default:
413 return "UNKNOWNSTATUS_ERROR";
414 }
415}
416
417static void ipw_dump_nic_error_log(struct ipw_priv *priv)
418{
419 u32 desc, time, blink1, blink2, ilink1, ilink2, idata, i, count, base;
420
421 base = ipw_read32(priv, IPWSTATUS_ERROR_LOG);
422 count = ipw_read_reg32(priv, base);
423
424 if (ERROR_START_OFFSET <= count * ERROR_ELEM_SIZE) {
425 IPW_ERROR("Start IPW Error Log Dump:\n");
426 IPW_ERROR("Status: 0x%08X, Config: %08X\n",
427 priv->status, priv->config);
428 }
429
430 for (i = ERROR_START_OFFSET;
431 i <= count * ERROR_ELEM_SIZE;
432 i += ERROR_ELEM_SIZE) {
433 desc = ipw_read_reg32(priv, base + i);
434 time = ipw_read_reg32(priv, base + i + 1*sizeof(u32));
435 blink1 = ipw_read_reg32(priv, base + i + 2*sizeof(u32));
436 blink2 = ipw_read_reg32(priv, base + i + 3*sizeof(u32));
437 ilink1 = ipw_read_reg32(priv, base + i + 4*sizeof(u32));
438 ilink2 = ipw_read_reg32(priv, base + i + 5*sizeof(u32));
439 idata = ipw_read_reg32(priv, base + i + 6*sizeof(u32));
440
441 IPW_ERROR(
442 "%s %i 0x%08x 0x%08x 0x%08x 0x%08x 0x%08x\n",
443 ipw_error_desc(desc), time, blink1, blink2,
444 ilink1, ilink2, idata);
445 }
446}
447
448static void ipw_dump_nic_event_log(struct ipw_priv *priv)
449{
450 u32 ev, time, data, i, count, base;
451
452 base = ipw_read32(priv, IPW_EVENT_LOG);
453 count = ipw_read_reg32(priv, base);
454
455 if (EVENT_START_OFFSET <= count * EVENT_ELEM_SIZE)
456 IPW_ERROR("Start IPW Event Log Dump:\n");
457
458 for (i = EVENT_START_OFFSET;
459 i <= count * EVENT_ELEM_SIZE;
460 i += EVENT_ELEM_SIZE) {
461 ev = ipw_read_reg32(priv, base + i);
462 time = ipw_read_reg32(priv, base + i + 1*sizeof(u32));
463 data = ipw_read_reg32(priv, base + i + 2*sizeof(u32));
464
465#ifdef CONFIG_IPW_DEBUG
466 IPW_ERROR("%i\t0x%08x\t%i\n", time, data, ev);
467#endif
468 }
469}
470
471static int ipw_get_ordinal(struct ipw_priv *priv, u32 ord, void *val,
472 u32 *len)
473{
474 u32 addr, field_info, field_len, field_count, total_len;
475
476 IPW_DEBUG_ORD("ordinal = %i\n", ord);
477
478 if (!priv || !val || !len) {
479 IPW_DEBUG_ORD("Invalid argument\n");
480 return -EINVAL;
481 }
482
483 /* verify device ordinal tables have been initialized */
484 if (!priv->table0_addr || !priv->table1_addr || !priv->table2_addr) {
485 IPW_DEBUG_ORD("Access ordinals before initialization\n");
486 return -EINVAL;
487 }
488
489 switch (IPW_ORD_TABLE_ID_MASK & ord) {
490 case IPW_ORD_TABLE_0_MASK:
491 /*
492 * TABLE 0: Direct access to a table of 32 bit values
493 *
494 * This is a very simple table with the data directly
495 * read from the table
496 */
497
498 /* remove the table id from the ordinal */
499 ord &= IPW_ORD_TABLE_VALUE_MASK;
500
501 /* boundary check */
502 if (ord > priv->table0_len) {
503 IPW_DEBUG_ORD("ordinal value (%i) longer then "
504 "max (%i)\n", ord, priv->table0_len);
505 return -EINVAL;
506 }
507
508 /* verify we have enough room to store the value */
509 if (*len < sizeof(u32)) {
510 IPW_DEBUG_ORD("ordinal buffer length too small, "
511 "need %zd\n", sizeof(u32));
512 return -EINVAL;
513 }
514
515 IPW_DEBUG_ORD("Reading TABLE0[%i] from offset 0x%08x\n",
516 ord, priv->table0_addr + (ord << 2));
517
518 *len = sizeof(u32);
519 ord <<= 2;
520 *((u32 *)val) = ipw_read32(priv, priv->table0_addr + ord);
521 break;
522
523 case IPW_ORD_TABLE_1_MASK:
524 /*
525 * TABLE 1: Indirect access to a table of 32 bit values
526 *
527 * This is a fairly large table of u32 values each
528 * representing starting addr for the data (which is
529 * also a u32)
530 */
531
532 /* remove the table id from the ordinal */
533 ord &= IPW_ORD_TABLE_VALUE_MASK;
534
535 /* boundary check */
536 if (ord > priv->table1_len) {
537 IPW_DEBUG_ORD("ordinal value too long\n");
538 return -EINVAL;
539 }
540
541 /* verify we have enough room to store the value */
542 if (*len < sizeof(u32)) {
543 IPW_DEBUG_ORD("ordinal buffer length too small, "
544 "need %zd\n", sizeof(u32));
545 return -EINVAL;
546 }
547
548 *((u32 *)val) = ipw_read_reg32(priv, (priv->table1_addr + (ord << 2)));
549 *len = sizeof(u32);
550 break;
551
552 case IPW_ORD_TABLE_2_MASK:
553 /*
554 * TABLE 2: Indirect access to a table of variable sized values
555 *
556 * This table consist of six values, each containing
557 * - dword containing the starting offset of the data
558 * - dword containing the lengh in the first 16bits
559 * and the count in the second 16bits
560 */
561
562 /* remove the table id from the ordinal */
563 ord &= IPW_ORD_TABLE_VALUE_MASK;
564
565 /* boundary check */
566 if (ord > priv->table2_len) {
567 IPW_DEBUG_ORD("ordinal value too long\n");
568 return -EINVAL;
569 }
570
571 /* get the address of statistic */
572 addr = ipw_read_reg32(priv, priv->table2_addr + (ord << 3));
573
574 /* get the second DW of statistics ;
575 * two 16-bit words - first is length, second is count */
576 field_info = ipw_read_reg32(priv, priv->table2_addr + (ord << 3) + sizeof(u32));
577
578 /* get each entry length */
579 field_len = *((u16 *)&field_info);
580
581 /* get number of entries */
582 field_count = *(((u16 *)&field_info) + 1);
583
584 /* abort if not enought memory */
585 total_len = field_len * field_count;
586 if (total_len > *len) {
587 *len = total_len;
588 return -EINVAL;
589 }
590
591 *len = total_len;
592 if (!total_len)
593 return 0;
594
595 IPW_DEBUG_ORD("addr = 0x%08x, total_len = %i, "
596 "field_info = 0x%08x\n",
597 addr, total_len, field_info);
598 ipw_read_indirect(priv, addr, val, total_len);
599 break;
600
601 default:
602 IPW_DEBUG_ORD("Invalid ordinal!\n");
603 return -EINVAL;
604
605 }
606
607
608 return 0;
609}
610
611static void ipw_init_ordinals(struct ipw_priv *priv)
612{
613 priv->table0_addr = IPW_ORDINALS_TABLE_LOWER;
614 priv->table0_len = ipw_read32(priv, priv->table0_addr);
615
616 IPW_DEBUG_ORD("table 0 offset at 0x%08x, len = %i\n",
617 priv->table0_addr, priv->table0_len);
618
619 priv->table1_addr = ipw_read32(priv, IPW_ORDINALS_TABLE_1);
620 priv->table1_len = ipw_read_reg32(priv, priv->table1_addr);
621
622 IPW_DEBUG_ORD("table 1 offset at 0x%08x, len = %i\n",
623 priv->table1_addr, priv->table1_len);
624
625 priv->table2_addr = ipw_read32(priv, IPW_ORDINALS_TABLE_2);
626 priv->table2_len = ipw_read_reg32(priv, priv->table2_addr);
627 priv->table2_len &= 0x0000ffff; /* use first two bytes */
628
629 IPW_DEBUG_ORD("table 2 offset at 0x%08x, len = %i\n",
630 priv->table2_addr, priv->table2_len);
631
632}
633
634/*
635 * The following adds a new attribute to the sysfs representation
636 * of this device driver (i.e. a new file in /sys/bus/pci/drivers/ipw/)
637 * used for controling the debug level.
638 *
639 * See the level definitions in ipw for details.
640 */
641static ssize_t show_debug_level(struct device_driver *d, char *buf)
642{
643 return sprintf(buf, "0x%08X\n", ipw_debug_level);
644}
645static ssize_t store_debug_level(struct device_driver *d,
646 const char *buf, size_t count)
647{
648 char *p = (char *)buf;
649 u32 val;
650
651 if (p[1] == 'x' || p[1] == 'X' || p[0] == 'x' || p[0] == 'X') {
652 p++;
653 if (p[0] == 'x' || p[0] == 'X')
654 p++;
655 val = simple_strtoul(p, &p, 16);
656 } else
657 val = simple_strtoul(p, &p, 10);
658 if (p == buf)
659 printk(KERN_INFO DRV_NAME
660 ": %s is not in hex or decimal form.\n", buf);
661 else
662 ipw_debug_level = val;
663
664 return strnlen(buf, count);
665}
666
667static DRIVER_ATTR(debug_level, S_IWUSR | S_IRUGO,
668 show_debug_level, store_debug_level);
669
670static ssize_t show_status(struct device *d,
671 struct device_attribute *attr, char *buf)
672{
673 struct ipw_priv *p = d->driver_data;
674 return sprintf(buf, "0x%08x\n", (int)p->status);
675}
676static DEVICE_ATTR(status, S_IRUGO, show_status, NULL);
677
678static ssize_t show_cfg(struct device *d, struct device_attribute *attr,
679 char *buf)
680{
681 struct ipw_priv *p = d->driver_data;
682 return sprintf(buf, "0x%08x\n", (int)p->config);
683}
684static DEVICE_ATTR(cfg, S_IRUGO, show_cfg, NULL);
685
686static ssize_t show_nic_type(struct device *d,
687 struct device_attribute *attr, char *buf)
688{
689 struct ipw_priv *p = d->driver_data;
690 u8 type = p->eeprom[EEPROM_NIC_TYPE];
691
692 switch (type) {
693 case EEPROM_NIC_TYPE_STANDARD:
694 return sprintf(buf, "STANDARD\n");
695 case EEPROM_NIC_TYPE_DELL:
696 return sprintf(buf, "DELL\n");
697 case EEPROM_NIC_TYPE_FUJITSU:
698 return sprintf(buf, "FUJITSU\n");
699 case EEPROM_NIC_TYPE_IBM:
700 return sprintf(buf, "IBM\n");
701 case EEPROM_NIC_TYPE_HP:
702 return sprintf(buf, "HP\n");
703 }
704
705 return sprintf(buf, "UNKNOWN\n");
706}
707static DEVICE_ATTR(nic_type, S_IRUGO, show_nic_type, NULL);
708
709static ssize_t dump_error_log(struct device *d,
710 struct device_attribute *attr, const char *buf, size_t count)
711{
712 char *p = (char *)buf;
713
714 if (p[0] == '1')
715 ipw_dump_nic_error_log((struct ipw_priv*)d->driver_data);
716
717 return strnlen(buf, count);
718}
719static DEVICE_ATTR(dump_errors, S_IWUSR, NULL, dump_error_log);
720
721static ssize_t dump_event_log(struct device *d,
722 struct device_attribute *attr, const char *buf, size_t count)
723{
724 char *p = (char *)buf;
725
726 if (p[0] == '1')
727 ipw_dump_nic_event_log((struct ipw_priv*)d->driver_data);
728
729 return strnlen(buf, count);
730}
731static DEVICE_ATTR(dump_events, S_IWUSR, NULL, dump_event_log);
732
733static ssize_t show_ucode_version(struct device *d,
734 struct device_attribute *attr, char *buf)
735{
736 u32 len = sizeof(u32), tmp = 0;
737 struct ipw_priv *p = d->driver_data;
738
739 if(ipw_get_ordinal(p, IPW_ORD_STAT_UCODE_VERSION, &tmp, &len))
740 return 0;
741
742 return sprintf(buf, "0x%08x\n", tmp);
743}
744static DEVICE_ATTR(ucode_version, S_IWUSR|S_IRUGO, show_ucode_version, NULL);
745
746static ssize_t show_rtc(struct device *d, struct device_attribute *attr,
747 char *buf)
748{
749 u32 len = sizeof(u32), tmp = 0;
750 struct ipw_priv *p = d->driver_data;
751
752 if(ipw_get_ordinal(p, IPW_ORD_STAT_RTC, &tmp, &len))
753 return 0;
754
755 return sprintf(buf, "0x%08x\n", tmp);
756}
757static DEVICE_ATTR(rtc, S_IWUSR|S_IRUGO, show_rtc, NULL);
758
759/*
760 * Add a device attribute to view/control the delay between eeprom
761 * operations.
762 */
763static ssize_t show_eeprom_delay(struct device *d,
764 struct device_attribute *attr, char *buf)
765{
766 int n = ((struct ipw_priv*)d->driver_data)->eeprom_delay;
767 return sprintf(buf, "%i\n", n);
768}
769static ssize_t store_eeprom_delay(struct device *d,
770 struct device_attribute *attr, const char *buf,
771 size_t count)
772{
773 struct ipw_priv *p = d->driver_data;
774 sscanf(buf, "%i", &p->eeprom_delay);
775 return strnlen(buf, count);
776}
777static DEVICE_ATTR(eeprom_delay, S_IWUSR|S_IRUGO,
778 show_eeprom_delay,store_eeprom_delay);
779
780static ssize_t show_command_event_reg(struct device *d,
781 struct device_attribute *attr, char *buf)
782{
783 u32 reg = 0;
784 struct ipw_priv *p = d->driver_data;
785
786 reg = ipw_read_reg32(p, CX2_INTERNAL_CMD_EVENT);
787 return sprintf(buf, "0x%08x\n", reg);
788}
789static ssize_t store_command_event_reg(struct device *d,
790 struct device_attribute *attr, const char *buf,
791 size_t count)
792{
793 u32 reg;
794 struct ipw_priv *p = d->driver_data;
795
796 sscanf(buf, "%x", &reg);
797 ipw_write_reg32(p, CX2_INTERNAL_CMD_EVENT, reg);
798 return strnlen(buf, count);
799}
800static DEVICE_ATTR(command_event_reg, S_IWUSR|S_IRUGO,
801 show_command_event_reg,store_command_event_reg);
802
803static ssize_t show_mem_gpio_reg(struct device *d,
804 struct device_attribute *attr, char *buf)
805{
806 u32 reg = 0;
807 struct ipw_priv *p = d->driver_data;
808
809 reg = ipw_read_reg32(p, 0x301100);
810 return sprintf(buf, "0x%08x\n", reg);
811}
812static ssize_t store_mem_gpio_reg(struct device *d,
813 struct device_attribute *attr, const char *buf,
814 size_t count)
815{
816 u32 reg;
817 struct ipw_priv *p = d->driver_data;
818
819 sscanf(buf, "%x", &reg);
820 ipw_write_reg32(p, 0x301100, reg);
821 return strnlen(buf, count);
822}
823static DEVICE_ATTR(mem_gpio_reg, S_IWUSR|S_IRUGO,
824 show_mem_gpio_reg,store_mem_gpio_reg);
825
826static ssize_t show_indirect_dword(struct device *d,
827 struct device_attribute *attr, char *buf)
828{
829 u32 reg = 0;
830 struct ipw_priv *priv = d->driver_data;
831 if (priv->status & STATUS_INDIRECT_DWORD)
832 reg = ipw_read_reg32(priv, priv->indirect_dword);
833 else
834 reg = 0;
835
836 return sprintf(buf, "0x%08x\n", reg);
837}
838static ssize_t store_indirect_dword(struct device *d,
839 struct device_attribute *attr, const char *buf,
840 size_t count)
841{
842 struct ipw_priv *priv = d->driver_data;
843
844 sscanf(buf, "%x", &priv->indirect_dword);
845 priv->status |= STATUS_INDIRECT_DWORD;
846 return strnlen(buf, count);
847}
848static DEVICE_ATTR(indirect_dword, S_IWUSR|S_IRUGO,
849 show_indirect_dword,store_indirect_dword);
850
851static ssize_t show_indirect_byte(struct device *d,
852 struct device_attribute *attr, char *buf)
853{
854 u8 reg = 0;
855 struct ipw_priv *priv = d->driver_data;
856 if (priv->status & STATUS_INDIRECT_BYTE)
857 reg = ipw_read_reg8(priv, priv->indirect_byte);
858 else
859 reg = 0;
860
861 return sprintf(buf, "0x%02x\n", reg);
862}
863static ssize_t store_indirect_byte(struct device *d,
864 struct device_attribute *attr, const char *buf,
865 size_t count)
866{
867 struct ipw_priv *priv = d->driver_data;
868
869 sscanf(buf, "%x", &priv->indirect_byte);
870 priv->status |= STATUS_INDIRECT_BYTE;
871 return strnlen(buf, count);
872}
873static DEVICE_ATTR(indirect_byte, S_IWUSR|S_IRUGO,
874 show_indirect_byte, store_indirect_byte);
875
876static ssize_t show_direct_dword(struct device *d,
877 struct device_attribute *attr, char *buf)
878{
879 u32 reg = 0;
880 struct ipw_priv *priv = d->driver_data;
881
882 if (priv->status & STATUS_DIRECT_DWORD)
883 reg = ipw_read32(priv, priv->direct_dword);
884 else
885 reg = 0;
886
887 return sprintf(buf, "0x%08x\n", reg);
888}
889static ssize_t store_direct_dword(struct device *d,
890 struct device_attribute *attr, const char *buf,
891 size_t count)
892{
893 struct ipw_priv *priv = d->driver_data;
894
895 sscanf(buf, "%x", &priv->direct_dword);
896 priv->status |= STATUS_DIRECT_DWORD;
897 return strnlen(buf, count);
898}
899static DEVICE_ATTR(direct_dword, S_IWUSR|S_IRUGO,
900 show_direct_dword,store_direct_dword);
901
902
903static inline int rf_kill_active(struct ipw_priv *priv)
904{
905 if (0 == (ipw_read32(priv, 0x30) & 0x10000))
906 priv->status |= STATUS_RF_KILL_HW;
907 else
908 priv->status &= ~STATUS_RF_KILL_HW;
909
910 return (priv->status & STATUS_RF_KILL_HW) ? 1 : 0;
911}
912
913static ssize_t show_rf_kill(struct device *d, struct device_attribute *attr,
914 char *buf)
915{
916 /* 0 - RF kill not enabled
917 1 - SW based RF kill active (sysfs)
918 2 - HW based RF kill active
919 3 - Both HW and SW baed RF kill active */
920 struct ipw_priv *priv = d->driver_data;
921 int val = ((priv->status & STATUS_RF_KILL_SW) ? 0x1 : 0x0) |
922 (rf_kill_active(priv) ? 0x2 : 0x0);
923 return sprintf(buf, "%i\n", val);
924}
925
926static int ipw_radio_kill_sw(struct ipw_priv *priv, int disable_radio)
927{
928 if ((disable_radio ? 1 : 0) ==
929 (priv->status & STATUS_RF_KILL_SW ? 1 : 0))
930 return 0 ;
931
932 IPW_DEBUG_RF_KILL("Manual SW RF Kill set to: RADIO %s\n",
933 disable_radio ? "OFF" : "ON");
934
935 if (disable_radio) {
936 priv->status |= STATUS_RF_KILL_SW;
937
938 if (priv->workqueue) {
939 cancel_delayed_work(&priv->request_scan);
940 }
941 wake_up_interruptible(&priv->wait_command_queue);
942 queue_work(priv->workqueue, &priv->down);
943 } else {
944 priv->status &= ~STATUS_RF_KILL_SW;
945 if (rf_kill_active(priv)) {
946 IPW_DEBUG_RF_KILL("Can not turn radio back on - "
947 "disabled by HW switch\n");
948 /* Make sure the RF_KILL check timer is running */
949 cancel_delayed_work(&priv->rf_kill);
950 queue_delayed_work(priv->workqueue, &priv->rf_kill,
951 2 * HZ);
952 } else
953 queue_work(priv->workqueue, &priv->up);
954 }
955
956 return 1;
957}
958
959static ssize_t store_rf_kill(struct device *d, struct device_attribute *attr,
960 const char *buf, size_t count)
961{
962 struct ipw_priv *priv = d->driver_data;
963
964 ipw_radio_kill_sw(priv, buf[0] == '1');
965
966 return count;
967}
968static DEVICE_ATTR(rf_kill, S_IWUSR|S_IRUGO, show_rf_kill, store_rf_kill);
969
970static void ipw_irq_tasklet(struct ipw_priv *priv)
971{
972 u32 inta, inta_mask, handled = 0;
973 unsigned long flags;
974 int rc = 0;
975
976 spin_lock_irqsave(&priv->lock, flags);
977
978 inta = ipw_read32(priv, CX2_INTA_RW);
979 inta_mask = ipw_read32(priv, CX2_INTA_MASK_R);
980 inta &= (CX2_INTA_MASK_ALL & inta_mask);
981
982 /* Add any cached INTA values that need to be handled */
983 inta |= priv->isr_inta;
984
985 /* handle all the justifications for the interrupt */
986 if (inta & CX2_INTA_BIT_RX_TRANSFER) {
987 ipw_rx(priv);
988 handled |= CX2_INTA_BIT_RX_TRANSFER;
989 }
990
991 if (inta & CX2_INTA_BIT_TX_CMD_QUEUE) {
992 IPW_DEBUG_HC("Command completed.\n");
993 rc = ipw_queue_tx_reclaim( priv, &priv->txq_cmd, -1);
994 priv->status &= ~STATUS_HCMD_ACTIVE;
995 wake_up_interruptible(&priv->wait_command_queue);
996 handled |= CX2_INTA_BIT_TX_CMD_QUEUE;
997 }
998
999 if (inta & CX2_INTA_BIT_TX_QUEUE_1) {
1000 IPW_DEBUG_TX("TX_QUEUE_1\n");
1001 rc = ipw_queue_tx_reclaim( priv, &priv->txq[0], 0);
1002 handled |= CX2_INTA_BIT_TX_QUEUE_1;
1003 }
1004
1005 if (inta & CX2_INTA_BIT_TX_QUEUE_2) {
1006 IPW_DEBUG_TX("TX_QUEUE_2\n");
1007 rc = ipw_queue_tx_reclaim( priv, &priv->txq[1], 1);
1008 handled |= CX2_INTA_BIT_TX_QUEUE_2;
1009 }
1010
1011 if (inta & CX2_INTA_BIT_TX_QUEUE_3) {
1012 IPW_DEBUG_TX("TX_QUEUE_3\n");
1013 rc = ipw_queue_tx_reclaim( priv, &priv->txq[2], 2);
1014 handled |= CX2_INTA_BIT_TX_QUEUE_3;
1015 }
1016
1017 if (inta & CX2_INTA_BIT_TX_QUEUE_4) {
1018 IPW_DEBUG_TX("TX_QUEUE_4\n");
1019 rc = ipw_queue_tx_reclaim( priv, &priv->txq[3], 3);
1020 handled |= CX2_INTA_BIT_TX_QUEUE_4;
1021 }
1022
1023 if (inta & CX2_INTA_BIT_STATUS_CHANGE) {
1024 IPW_WARNING("STATUS_CHANGE\n");
1025 handled |= CX2_INTA_BIT_STATUS_CHANGE;
1026 }
1027
1028 if (inta & CX2_INTA_BIT_BEACON_PERIOD_EXPIRED) {
1029 IPW_WARNING("TX_PERIOD_EXPIRED\n");
1030 handled |= CX2_INTA_BIT_BEACON_PERIOD_EXPIRED;
1031 }
1032
1033 if (inta & CX2_INTA_BIT_SLAVE_MODE_HOST_CMD_DONE) {
1034 IPW_WARNING("HOST_CMD_DONE\n");
1035 handled |= CX2_INTA_BIT_SLAVE_MODE_HOST_CMD_DONE;
1036 }
1037
1038 if (inta & CX2_INTA_BIT_FW_INITIALIZATION_DONE) {
1039 IPW_WARNING("FW_INITIALIZATION_DONE\n");
1040 handled |= CX2_INTA_BIT_FW_INITIALIZATION_DONE;
1041 }
1042
1043 if (inta & CX2_INTA_BIT_FW_CARD_DISABLE_PHY_OFF_DONE) {
1044 IPW_WARNING("PHY_OFF_DONE\n");
1045 handled |= CX2_INTA_BIT_FW_CARD_DISABLE_PHY_OFF_DONE;
1046 }
1047
1048 if (inta & CX2_INTA_BIT_RF_KILL_DONE) {
1049 IPW_DEBUG_RF_KILL("RF_KILL_DONE\n");
1050 priv->status |= STATUS_RF_KILL_HW;
1051 wake_up_interruptible(&priv->wait_command_queue);
1052 netif_carrier_off(priv->net_dev);
1053 netif_stop_queue(priv->net_dev);
1054 cancel_delayed_work(&priv->request_scan);
1055 queue_delayed_work(priv->workqueue, &priv->rf_kill, 2 * HZ);
1056 handled |= CX2_INTA_BIT_RF_KILL_DONE;
1057 }
1058
1059 if (inta & CX2_INTA_BIT_FATAL_ERROR) {
1060 IPW_ERROR("Firmware error detected. Restarting.\n");
1061#ifdef CONFIG_IPW_DEBUG
1062 if (ipw_debug_level & IPW_DL_FW_ERRORS) {
1063 ipw_dump_nic_error_log(priv);
1064 ipw_dump_nic_event_log(priv);
1065 }
1066#endif
1067 queue_work(priv->workqueue, &priv->adapter_restart);
1068 handled |= CX2_INTA_BIT_FATAL_ERROR;
1069 }
1070
1071 if (inta & CX2_INTA_BIT_PARITY_ERROR) {
1072 IPW_ERROR("Parity error\n");
1073 handled |= CX2_INTA_BIT_PARITY_ERROR;
1074 }
1075
1076 if (handled != inta) {
1077 IPW_ERROR("Unhandled INTA bits 0x%08x\n",
1078 inta & ~handled);
1079 }
1080
1081 /* enable all interrupts */
1082 ipw_enable_interrupts(priv);
1083
1084 spin_unlock_irqrestore(&priv->lock, flags);
1085}
1086
1087#ifdef CONFIG_IPW_DEBUG
1088#define IPW_CMD(x) case IPW_CMD_ ## x : return #x
1089static char *get_cmd_string(u8 cmd)
1090{
1091 switch (cmd) {
1092 IPW_CMD(HOST_COMPLETE);
1093 IPW_CMD(POWER_DOWN);
1094 IPW_CMD(SYSTEM_CONFIG);
1095 IPW_CMD(MULTICAST_ADDRESS);
1096 IPW_CMD(SSID);
1097 IPW_CMD(ADAPTER_ADDRESS);
1098 IPW_CMD(PORT_TYPE);
1099 IPW_CMD(RTS_THRESHOLD);
1100 IPW_CMD(FRAG_THRESHOLD);
1101 IPW_CMD(POWER_MODE);
1102 IPW_CMD(WEP_KEY);
1103 IPW_CMD(TGI_TX_KEY);
1104 IPW_CMD(SCAN_REQUEST);
1105 IPW_CMD(SCAN_REQUEST_EXT);
1106 IPW_CMD(ASSOCIATE);
1107 IPW_CMD(SUPPORTED_RATES);
1108 IPW_CMD(SCAN_ABORT);
1109 IPW_CMD(TX_FLUSH);
1110 IPW_CMD(QOS_PARAMETERS);
1111 IPW_CMD(DINO_CONFIG);
1112 IPW_CMD(RSN_CAPABILITIES);
1113 IPW_CMD(RX_KEY);
1114 IPW_CMD(CARD_DISABLE);
1115 IPW_CMD(SEED_NUMBER);
1116 IPW_CMD(TX_POWER);
1117 IPW_CMD(COUNTRY_INFO);
1118 IPW_CMD(AIRONET_INFO);
1119 IPW_CMD(AP_TX_POWER);
1120 IPW_CMD(CCKM_INFO);
1121 IPW_CMD(CCX_VER_INFO);
1122 IPW_CMD(SET_CALIBRATION);
1123 IPW_CMD(SENSITIVITY_CALIB);
1124 IPW_CMD(RETRY_LIMIT);
1125 IPW_CMD(IPW_PRE_POWER_DOWN);
1126 IPW_CMD(VAP_BEACON_TEMPLATE);
1127 IPW_CMD(VAP_DTIM_PERIOD);
1128 IPW_CMD(EXT_SUPPORTED_RATES);
1129 IPW_CMD(VAP_LOCAL_TX_PWR_CONSTRAINT);
1130 IPW_CMD(VAP_QUIET_INTERVALS);
1131 IPW_CMD(VAP_CHANNEL_SWITCH);
1132 IPW_CMD(VAP_MANDATORY_CHANNELS);
1133 IPW_CMD(VAP_CELL_PWR_LIMIT);
1134 IPW_CMD(VAP_CF_PARAM_SET);
1135 IPW_CMD(VAP_SET_BEACONING_STATE);
1136 IPW_CMD(MEASUREMENT);
1137 IPW_CMD(POWER_CAPABILITY);
1138 IPW_CMD(SUPPORTED_CHANNELS);
1139 IPW_CMD(TPC_REPORT);
1140 IPW_CMD(WME_INFO);
1141 IPW_CMD(PRODUCTION_COMMAND);
1142 default:
1143 return "UNKNOWN";
1144 }
1145}
1146#endif /* CONFIG_IPW_DEBUG */
1147
1148#define HOST_COMPLETE_TIMEOUT HZ
1149static int ipw_send_cmd(struct ipw_priv *priv, struct host_cmd *cmd)
1150{
1151 int rc = 0;
1152
1153 if (priv->status & STATUS_HCMD_ACTIVE) {
1154 IPW_ERROR("Already sending a command\n");
1155 return -1;
1156 }
1157
1158 priv->status |= STATUS_HCMD_ACTIVE;
1159
1160 IPW_DEBUG_HC("Sending %s command (#%d), %d bytes\n",
1161 get_cmd_string(cmd->cmd), cmd->cmd, cmd->len);
1162 printk_buf(IPW_DL_HOST_COMMAND, (u8*)cmd->param, cmd->len);
1163
1164 rc = ipw_queue_tx_hcmd(priv, cmd->cmd, &cmd->param, cmd->len, 0);
1165 if (rc)
1166 return rc;
1167
1168 rc = wait_event_interruptible_timeout(
1169 priv->wait_command_queue, !(priv->status & STATUS_HCMD_ACTIVE),
1170 HOST_COMPLETE_TIMEOUT);
1171 if (rc == 0) {
1172 IPW_DEBUG_INFO("Command completion failed out after %dms.\n",
1173 jiffies_to_msecs(HOST_COMPLETE_TIMEOUT));
1174 priv->status &= ~STATUS_HCMD_ACTIVE;
1175 return -EIO;
1176 }
1177 if (priv->status & STATUS_RF_KILL_MASK) {
1178 IPW_DEBUG_INFO("Command aborted due to RF Kill Switch\n");
1179 return -EIO;
1180 }
1181
1182 return 0;
1183}
1184
1185static int ipw_send_host_complete(struct ipw_priv *priv)
1186{
1187 struct host_cmd cmd = {
1188 .cmd = IPW_CMD_HOST_COMPLETE,
1189 .len = 0
1190 };
1191
1192 if (!priv) {
1193 IPW_ERROR("Invalid args\n");
1194 return -1;
1195 }
1196
1197 if (ipw_send_cmd(priv, &cmd)) {
1198 IPW_ERROR("failed to send HOST_COMPLETE command\n");
1199 return -1;
1200 }
1201
1202 return 0;
1203}
1204
1205static int ipw_send_system_config(struct ipw_priv *priv,
1206 struct ipw_sys_config *config)
1207{
1208 struct host_cmd cmd = {
1209 .cmd = IPW_CMD_SYSTEM_CONFIG,
1210 .len = sizeof(*config)
1211 };
1212
1213 if (!priv || !config) {
1214 IPW_ERROR("Invalid args\n");
1215 return -1;
1216 }
1217
1218 memcpy(&cmd.param,config,sizeof(*config));
1219 if (ipw_send_cmd(priv, &cmd)) {
1220 IPW_ERROR("failed to send SYSTEM_CONFIG command\n");
1221 return -1;
1222 }
1223
1224 return 0;
1225}
1226
1227static int ipw_send_ssid(struct ipw_priv *priv, u8 *ssid, int len)
1228{
1229 struct host_cmd cmd = {
1230 .cmd = IPW_CMD_SSID,
1231 .len = min(len, IW_ESSID_MAX_SIZE)
1232 };
1233
1234 if (!priv || !ssid) {
1235 IPW_ERROR("Invalid args\n");
1236 return -1;
1237 }
1238
1239 memcpy(&cmd.param, ssid, cmd.len);
1240 if (ipw_send_cmd(priv, &cmd)) {
1241 IPW_ERROR("failed to send SSID command\n");
1242 return -1;
1243 }
1244
1245 return 0;
1246}
1247
1248static int ipw_send_adapter_address(struct ipw_priv *priv, u8 *mac)
1249{
1250 struct host_cmd cmd = {
1251 .cmd = IPW_CMD_ADAPTER_ADDRESS,
1252 .len = ETH_ALEN
1253 };
1254
1255 if (!priv || !mac) {
1256 IPW_ERROR("Invalid args\n");
1257 return -1;
1258 }
1259
1260 IPW_DEBUG_INFO("%s: Setting MAC to " MAC_FMT "\n",
1261 priv->net_dev->name, MAC_ARG(mac));
1262
1263 memcpy(&cmd.param, mac, ETH_ALEN);
1264
1265 if (ipw_send_cmd(priv, &cmd)) {
1266 IPW_ERROR("failed to send ADAPTER_ADDRESS command\n");
1267 return -1;
1268 }
1269
1270 return 0;
1271}
1272
1273static void ipw_adapter_restart(void *adapter)
1274{
1275 struct ipw_priv *priv = adapter;
1276
1277 if (priv->status & STATUS_RF_KILL_MASK)
1278 return;
1279
1280 ipw_down(priv);
1281 if (ipw_up(priv)) {
1282 IPW_ERROR("Failed to up device\n");
1283 return;
1284 }
1285}
1286
1287
1288
1289
1290#define IPW_SCAN_CHECK_WATCHDOG (5 * HZ)
1291
1292static void ipw_scan_check(void *data)
1293{
1294 struct ipw_priv *priv = data;
1295 if (priv->status & (STATUS_SCANNING | STATUS_SCAN_ABORTING)) {
1296 IPW_DEBUG_SCAN("Scan completion watchdog resetting "
1297 "adapter (%dms).\n",
1298 IPW_SCAN_CHECK_WATCHDOG / 100);
1299 ipw_adapter_restart(priv);
1300 }
1301}
1302
1303static int ipw_send_scan_request_ext(struct ipw_priv *priv,
1304 struct ipw_scan_request_ext *request)
1305{
1306 struct host_cmd cmd = {
1307 .cmd = IPW_CMD_SCAN_REQUEST_EXT,
1308 .len = sizeof(*request)
1309 };
1310
1311 if (!priv || !request) {
1312 IPW_ERROR("Invalid args\n");
1313 return -1;
1314 }
1315
1316 memcpy(&cmd.param,request,sizeof(*request));
1317 if (ipw_send_cmd(priv, &cmd)) {
1318 IPW_ERROR("failed to send SCAN_REQUEST_EXT command\n");
1319 return -1;
1320 }
1321
1322 queue_delayed_work(priv->workqueue, &priv->scan_check,
1323 IPW_SCAN_CHECK_WATCHDOG);
1324 return 0;
1325}
1326
1327static int ipw_send_scan_abort(struct ipw_priv *priv)
1328{
1329 struct host_cmd cmd = {
1330 .cmd = IPW_CMD_SCAN_ABORT,
1331 .len = 0
1332 };
1333
1334 if (!priv) {
1335 IPW_ERROR("Invalid args\n");
1336 return -1;
1337 }
1338
1339 if (ipw_send_cmd(priv, &cmd)) {
1340 IPW_ERROR("failed to send SCAN_ABORT command\n");
1341 return -1;
1342 }
1343
1344 return 0;
1345}
1346
1347static int ipw_set_sensitivity(struct ipw_priv *priv, u16 sens)
1348{
1349 struct host_cmd cmd = {
1350 .cmd = IPW_CMD_SENSITIVITY_CALIB,
1351 .len = sizeof(struct ipw_sensitivity_calib)
1352 };
1353 struct ipw_sensitivity_calib *calib = (struct ipw_sensitivity_calib *)
1354 &cmd.param;
1355 calib->beacon_rssi_raw = sens;
1356 if (ipw_send_cmd(priv, &cmd)) {
1357 IPW_ERROR("failed to send SENSITIVITY CALIB command\n");
1358 return -1;
1359 }
1360
1361 return 0;
1362}
1363
1364static int ipw_send_associate(struct ipw_priv *priv,
1365 struct ipw_associate *associate)
1366{
1367 struct host_cmd cmd = {
1368 .cmd = IPW_CMD_ASSOCIATE,
1369 .len = sizeof(*associate)
1370 };
1371
1372 if (!priv || !associate) {
1373 IPW_ERROR("Invalid args\n");
1374 return -1;
1375 }
1376
1377 memcpy(&cmd.param,associate,sizeof(*associate));
1378 if (ipw_send_cmd(priv, &cmd)) {
1379 IPW_ERROR("failed to send ASSOCIATE command\n");
1380 return -1;
1381 }
1382
1383 return 0;
1384}
1385
1386static int ipw_send_supported_rates(struct ipw_priv *priv,
1387 struct ipw_supported_rates *rates)
1388{
1389 struct host_cmd cmd = {
1390 .cmd = IPW_CMD_SUPPORTED_RATES,
1391 .len = sizeof(*rates)
1392 };
1393
1394 if (!priv || !rates) {
1395 IPW_ERROR("Invalid args\n");
1396 return -1;
1397 }
1398
1399 memcpy(&cmd.param,rates,sizeof(*rates));
1400 if (ipw_send_cmd(priv, &cmd)) {
1401 IPW_ERROR("failed to send SUPPORTED_RATES command\n");
1402 return -1;
1403 }
1404
1405 return 0;
1406}
1407
1408static int ipw_set_random_seed(struct ipw_priv *priv)
1409{
1410 struct host_cmd cmd = {
1411 .cmd = IPW_CMD_SEED_NUMBER,
1412 .len = sizeof(u32)
1413 };
1414
1415 if (!priv) {
1416 IPW_ERROR("Invalid args\n");
1417 return -1;
1418 }
1419
1420 get_random_bytes(&cmd.param, sizeof(u32));
1421
1422 if (ipw_send_cmd(priv, &cmd)) {
1423 IPW_ERROR("failed to send SEED_NUMBER command\n");
1424 return -1;
1425 }
1426
1427 return 0;
1428}
1429
1430#if 0
1431static int ipw_send_card_disable(struct ipw_priv *priv, u32 phy_off)
1432{
1433 struct host_cmd cmd = {
1434 .cmd = IPW_CMD_CARD_DISABLE,
1435 .len = sizeof(u32)
1436 };
1437
1438 if (!priv) {
1439 IPW_ERROR("Invalid args\n");
1440 return -1;
1441 }
1442
1443 *((u32*)&cmd.param) = phy_off;
1444
1445 if (ipw_send_cmd(priv, &cmd)) {
1446 IPW_ERROR("failed to send CARD_DISABLE command\n");
1447 return -1;
1448 }
1449
1450 return 0;
1451}
1452#endif
1453
1454static int ipw_send_tx_power(struct ipw_priv *priv,
1455 struct ipw_tx_power *power)
1456{
1457 struct host_cmd cmd = {
1458 .cmd = IPW_CMD_TX_POWER,
1459 .len = sizeof(*power)
1460 };
1461
1462 if (!priv || !power) {
1463 IPW_ERROR("Invalid args\n");
1464 return -1;
1465 }
1466
1467 memcpy(&cmd.param,power,sizeof(*power));
1468 if (ipw_send_cmd(priv, &cmd)) {
1469 IPW_ERROR("failed to send TX_POWER command\n");
1470 return -1;
1471 }
1472
1473 return 0;
1474}
1475
1476static int ipw_send_rts_threshold(struct ipw_priv *priv, u16 rts)
1477{
1478 struct ipw_rts_threshold rts_threshold = {
1479 .rts_threshold = rts,
1480 };
1481 struct host_cmd cmd = {
1482 .cmd = IPW_CMD_RTS_THRESHOLD,
1483 .len = sizeof(rts_threshold)
1484 };
1485
1486 if (!priv) {
1487 IPW_ERROR("Invalid args\n");
1488 return -1;
1489 }
1490
1491 memcpy(&cmd.param, &rts_threshold, sizeof(rts_threshold));
1492 if (ipw_send_cmd(priv, &cmd)) {
1493 IPW_ERROR("failed to send RTS_THRESHOLD command\n");
1494 return -1;
1495 }
1496
1497 return 0;
1498}
1499
1500static int ipw_send_frag_threshold(struct ipw_priv *priv, u16 frag)
1501{
1502 struct ipw_frag_threshold frag_threshold = {
1503 .frag_threshold = frag,
1504 };
1505 struct host_cmd cmd = {
1506 .cmd = IPW_CMD_FRAG_THRESHOLD,
1507 .len = sizeof(frag_threshold)
1508 };
1509
1510 if (!priv) {
1511 IPW_ERROR("Invalid args\n");
1512 return -1;
1513 }
1514
1515 memcpy(&cmd.param, &frag_threshold, sizeof(frag_threshold));
1516 if (ipw_send_cmd(priv, &cmd)) {
1517 IPW_ERROR("failed to send FRAG_THRESHOLD command\n");
1518 return -1;
1519 }
1520
1521 return 0;
1522}
1523
1524static int ipw_send_power_mode(struct ipw_priv *priv, u32 mode)
1525{
1526 struct host_cmd cmd = {
1527 .cmd = IPW_CMD_POWER_MODE,
1528 .len = sizeof(u32)
1529 };
1530 u32 *param = (u32*)(&cmd.param);
1531
1532 if (!priv) {
1533 IPW_ERROR("Invalid args\n");
1534 return -1;
1535 }
1536
1537 /* If on battery, set to 3, if AC set to CAM, else user
1538 * level */
1539 switch (mode) {
1540 case IPW_POWER_BATTERY:
1541 *param = IPW_POWER_INDEX_3;
1542 break;
1543 case IPW_POWER_AC:
1544 *param = IPW_POWER_MODE_CAM;
1545 break;
1546 default:
1547 *param = mode;
1548 break;
1549 }
1550
1551 if (ipw_send_cmd(priv, &cmd)) {
1552 IPW_ERROR("failed to send POWER_MODE command\n");
1553 return -1;
1554 }
1555
1556 return 0;
1557}
1558
1559/*
1560 * The IPW device contains a Microwire compatible EEPROM that stores
1561 * various data like the MAC address. Usually the firmware has exclusive
1562 * access to the eeprom, but during device initialization (before the
1563 * device driver has sent the HostComplete command to the firmware) the
1564 * device driver has read access to the EEPROM by way of indirect addressing
1565 * through a couple of memory mapped registers.
1566 *
1567 * The following is a simplified implementation for pulling data out of the
1568 * the eeprom, along with some helper functions to find information in
1569 * the per device private data's copy of the eeprom.
1570 *
1571 * NOTE: To better understand how these functions work (i.e what is a chip
1572 * select and why do have to keep driving the eeprom clock?), read
1573 * just about any data sheet for a Microwire compatible EEPROM.
1574 */
1575
1576/* write a 32 bit value into the indirect accessor register */
1577static inline void eeprom_write_reg(struct ipw_priv *p, u32 data)
1578{
1579 ipw_write_reg32(p, FW_MEM_REG_EEPROM_ACCESS, data);
1580
1581 /* the eeprom requires some time to complete the operation */
1582 udelay(p->eeprom_delay);
1583
1584 return;
1585}
1586
1587/* perform a chip select operation */
1588static inline void eeprom_cs(struct ipw_priv* priv)
1589{
1590 eeprom_write_reg(priv,0);
1591 eeprom_write_reg(priv,EEPROM_BIT_CS);
1592 eeprom_write_reg(priv,EEPROM_BIT_CS|EEPROM_BIT_SK);
1593 eeprom_write_reg(priv,EEPROM_BIT_CS);
1594}
1595
1596/* perform a chip select operation */
1597static inline void eeprom_disable_cs(struct ipw_priv* priv)
1598{
1599 eeprom_write_reg(priv,EEPROM_BIT_CS);
1600 eeprom_write_reg(priv,0);
1601 eeprom_write_reg(priv,EEPROM_BIT_SK);
1602}
1603
1604/* push a single bit down to the eeprom */
1605static inline void eeprom_write_bit(struct ipw_priv *p,u8 bit)
1606{
1607 int d = ( bit ? EEPROM_BIT_DI : 0);
1608 eeprom_write_reg(p,EEPROM_BIT_CS|d);
1609 eeprom_write_reg(p,EEPROM_BIT_CS|d|EEPROM_BIT_SK);
1610}
1611
1612/* push an opcode followed by an address down to the eeprom */
1613static void eeprom_op(struct ipw_priv* priv, u8 op, u8 addr)
1614{
1615 int i;
1616
1617 eeprom_cs(priv);
1618 eeprom_write_bit(priv,1);
1619 eeprom_write_bit(priv,op&2);
1620 eeprom_write_bit(priv,op&1);
1621 for ( i=7; i>=0; i-- ) {
1622 eeprom_write_bit(priv,addr&(1<<i));
1623 }
1624}
1625
1626/* pull 16 bits off the eeprom, one bit at a time */
1627static u16 eeprom_read_u16(struct ipw_priv* priv, u8 addr)
1628{
1629 int i;
1630 u16 r=0;
1631
1632 /* Send READ Opcode */
1633 eeprom_op(priv,EEPROM_CMD_READ,addr);
1634
1635 /* Send dummy bit */
1636 eeprom_write_reg(priv,EEPROM_BIT_CS);
1637
1638 /* Read the byte off the eeprom one bit at a time */
1639 for ( i=0; i<16; i++ ) {
1640 u32 data = 0;
1641 eeprom_write_reg(priv,EEPROM_BIT_CS|EEPROM_BIT_SK);
1642 eeprom_write_reg(priv,EEPROM_BIT_CS);
1643 data = ipw_read_reg32(priv,FW_MEM_REG_EEPROM_ACCESS);
1644 r = (r<<1) | ((data & EEPROM_BIT_DO)?1:0);
1645 }
1646
1647 /* Send another dummy bit */
1648 eeprom_write_reg(priv,0);
1649 eeprom_disable_cs(priv);
1650
1651 return r;
1652}
1653
1654/* helper function for pulling the mac address out of the private */
1655/* data's copy of the eeprom data */
1656static void eeprom_parse_mac(struct ipw_priv* priv, u8* mac)
1657{
1658 u8* ee = (u8*)priv->eeprom;
1659 memcpy(mac, &ee[EEPROM_MAC_ADDRESS], 6);
1660}
1661
1662/*
1663 * Either the device driver (i.e. the host) or the firmware can
1664 * load eeprom data into the designated region in SRAM. If neither
1665 * happens then the FW will shutdown with a fatal error.
1666 *
1667 * In order to signal the FW to load the EEPROM, the EEPROM_LOAD_DISABLE
1668 * bit needs region of shared SRAM needs to be non-zero.
1669 */
1670static void ipw_eeprom_init_sram(struct ipw_priv *priv)
1671{
1672 int i;
1673 u16 *eeprom = (u16 *)priv->eeprom;
1674
1675 IPW_DEBUG_TRACE(">>\n");
1676
1677 /* read entire contents of eeprom into private buffer */
1678 for ( i=0; i<128; i++ )
1679 eeprom[i] = eeprom_read_u16(priv,(u8)i);
1680
1681 /*
1682 If the data looks correct, then copy it to our private
1683 copy. Otherwise let the firmware know to perform the operation
1684 on it's own
1685 */
1686 if ((priv->eeprom + EEPROM_VERSION) != 0) {
1687 IPW_DEBUG_INFO("Writing EEPROM data into SRAM\n");
1688
1689 /* write the eeprom data to sram */
1690 for( i=0; i<CX2_EEPROM_IMAGE_SIZE; i++ )
1691 ipw_write8(priv, IPW_EEPROM_DATA + i,
1692 priv->eeprom[i]);
1693
1694 /* Do not load eeprom data on fatal error or suspend */
1695 ipw_write32(priv, IPW_EEPROM_LOAD_DISABLE, 0);
1696 } else {
1697 IPW_DEBUG_INFO("Enabling FW initializationg of SRAM\n");
1698
1699 /* Load eeprom data on fatal error or suspend */
1700 ipw_write32(priv, IPW_EEPROM_LOAD_DISABLE, 1);
1701 }
1702
1703 IPW_DEBUG_TRACE("<<\n");
1704}
1705
1706
1707static inline void ipw_zero_memory(struct ipw_priv *priv, u32 start, u32 count)
1708{
1709 count >>= 2;
1710 if (!count) return;
1711 _ipw_write32(priv, CX2_AUTOINC_ADDR, start);
1712 while (count--)
1713 _ipw_write32(priv, CX2_AUTOINC_DATA, 0);
1714}
1715
1716static inline void ipw_fw_dma_reset_command_blocks(struct ipw_priv *priv)
1717{
1718 ipw_zero_memory(priv, CX2_SHARED_SRAM_DMA_CONTROL,
1719 CB_NUMBER_OF_ELEMENTS_SMALL *
1720 sizeof(struct command_block));
1721}
1722
1723static int ipw_fw_dma_enable(struct ipw_priv *priv)
1724{ /* start dma engine but no transfers yet*/
1725
1726 IPW_DEBUG_FW(">> : \n");
1727
1728 /* Start the dma */
1729 ipw_fw_dma_reset_command_blocks(priv);
1730
1731 /* Write CB base address */
1732 ipw_write_reg32(priv, CX2_DMA_I_CB_BASE, CX2_SHARED_SRAM_DMA_CONTROL);
1733
1734 IPW_DEBUG_FW("<< : \n");
1735 return 0;
1736}
1737
1738static void ipw_fw_dma_abort(struct ipw_priv *priv)
1739{
1740 u32 control = 0;
1741
1742 IPW_DEBUG_FW(">> :\n");
1743
1744 //set the Stop and Abort bit
1745 control = DMA_CONTROL_SMALL_CB_CONST_VALUE | DMA_CB_STOP_AND_ABORT;
1746 ipw_write_reg32(priv, CX2_DMA_I_DMA_CONTROL, control);
1747 priv->sram_desc.last_cb_index = 0;
1748
1749 IPW_DEBUG_FW("<< \n");
1750}
1751
1752static int ipw_fw_dma_write_command_block(struct ipw_priv *priv, int index, struct command_block *cb)
1753{
1754 u32 address = CX2_SHARED_SRAM_DMA_CONTROL + (sizeof(struct command_block) * index);
1755 IPW_DEBUG_FW(">> :\n");
1756
1757 ipw_write_indirect(priv, address, (u8*)cb, (int)sizeof(struct command_block));
1758
1759 IPW_DEBUG_FW("<< :\n");
1760 return 0;
1761
1762}
1763
1764static int ipw_fw_dma_kick(struct ipw_priv *priv)
1765{
1766 u32 control = 0;
1767 u32 index=0;
1768
1769 IPW_DEBUG_FW(">> :\n");
1770
1771 for (index = 0; index < priv->sram_desc.last_cb_index; index++)
1772 ipw_fw_dma_write_command_block(priv, index, &priv->sram_desc.cb_list[index]);
1773
1774 /* Enable the DMA in the CSR register */
1775 ipw_clear_bit(priv, CX2_RESET_REG,CX2_RESET_REG_MASTER_DISABLED | CX2_RESET_REG_STOP_MASTER);
1776
1777 /* Set the Start bit. */
1778 control = DMA_CONTROL_SMALL_CB_CONST_VALUE | DMA_CB_START;
1779 ipw_write_reg32(priv, CX2_DMA_I_DMA_CONTROL, control);
1780
1781 IPW_DEBUG_FW("<< :\n");
1782 return 0;
1783}
1784
1785static void ipw_fw_dma_dump_command_block(struct ipw_priv *priv)
1786{
1787 u32 address;
1788 u32 register_value=0;
1789 u32 cb_fields_address=0;
1790
1791 IPW_DEBUG_FW(">> :\n");
1792 address = ipw_read_reg32(priv,CX2_DMA_I_CURRENT_CB);
1793 IPW_DEBUG_FW_INFO("Current CB is 0x%x \n",address);
1794
1795 /* Read the DMA Controlor register */
1796 register_value = ipw_read_reg32(priv, CX2_DMA_I_DMA_CONTROL);
1797 IPW_DEBUG_FW_INFO("CX2_DMA_I_DMA_CONTROL is 0x%x \n",register_value);
1798
1799 /* Print the CB values*/
1800 cb_fields_address = address;
1801 register_value = ipw_read_reg32(priv, cb_fields_address);
1802 IPW_DEBUG_FW_INFO("Current CB ControlField is 0x%x \n",register_value);
1803
1804 cb_fields_address += sizeof(u32);
1805 register_value = ipw_read_reg32(priv, cb_fields_address);
1806 IPW_DEBUG_FW_INFO("Current CB Source Field is 0x%x \n",register_value);
1807
1808 cb_fields_address += sizeof(u32);
1809 register_value = ipw_read_reg32(priv, cb_fields_address);
1810 IPW_DEBUG_FW_INFO("Current CB Destination Field is 0x%x \n",
1811 register_value);
1812
1813 cb_fields_address += sizeof(u32);
1814 register_value = ipw_read_reg32(priv, cb_fields_address);
1815 IPW_DEBUG_FW_INFO("Current CB Status Field is 0x%x \n",register_value);
1816
1817 IPW_DEBUG_FW(">> :\n");
1818}
1819
1820static int ipw_fw_dma_command_block_index(struct ipw_priv *priv)
1821{
1822 u32 current_cb_address = 0;
1823 u32 current_cb_index = 0;
1824
1825 IPW_DEBUG_FW("<< :\n");
1826 current_cb_address= ipw_read_reg32(priv, CX2_DMA_I_CURRENT_CB);
1827
1828 current_cb_index = (current_cb_address - CX2_SHARED_SRAM_DMA_CONTROL )/
1829 sizeof (struct command_block);
1830
1831 IPW_DEBUG_FW_INFO("Current CB index 0x%x address = 0x%X \n",
1832 current_cb_index, current_cb_address );
1833
1834 IPW_DEBUG_FW(">> :\n");
1835 return current_cb_index;
1836
1837}
1838
1839static int ipw_fw_dma_add_command_block(struct ipw_priv *priv,
1840 u32 src_address,
1841 u32 dest_address,
1842 u32 length,
1843 int interrupt_enabled,
1844 int is_last)
1845{
1846
1847 u32 control = CB_VALID | CB_SRC_LE | CB_DEST_LE | CB_SRC_AUTOINC |
1848 CB_SRC_IO_GATED | CB_DEST_AUTOINC | CB_SRC_SIZE_LONG |
1849 CB_DEST_SIZE_LONG;
1850 struct command_block *cb;
1851 u32 last_cb_element=0;
1852
1853 IPW_DEBUG_FW_INFO("src_address=0x%x dest_address=0x%x length=0x%x\n",
1854 src_address, dest_address, length);
1855
1856 if (priv->sram_desc.last_cb_index >= CB_NUMBER_OF_ELEMENTS_SMALL)
1857 return -1;
1858
1859 last_cb_element = priv->sram_desc.last_cb_index;
1860 cb = &priv->sram_desc.cb_list[last_cb_element];
1861 priv->sram_desc.last_cb_index++;
1862
1863 /* Calculate the new CB control word */
1864 if (interrupt_enabled )
1865 control |= CB_INT_ENABLED;
1866
1867 if (is_last)
1868 control |= CB_LAST_VALID;
1869
1870 control |= length;
1871
1872 /* Calculate the CB Element's checksum value */
1873 cb->status = control ^src_address ^dest_address;
1874
1875 /* Copy the Source and Destination addresses */
1876 cb->dest_addr = dest_address;
1877 cb->source_addr = src_address;
1878
1879 /* Copy the Control Word last */
1880 cb->control = control;
1881
1882 return 0;
1883}
1884
1885static int ipw_fw_dma_add_buffer(struct ipw_priv *priv,
1886 u32 src_phys,
1887 u32 dest_address,
1888 u32 length)
1889{
1890 u32 bytes_left = length;
1891 u32 src_offset=0;
1892 u32 dest_offset=0;
1893 int status = 0;
1894 IPW_DEBUG_FW(">> \n");
1895 IPW_DEBUG_FW_INFO("src_phys=0x%x dest_address=0x%x length=0x%x\n",
1896 src_phys, dest_address, length);
1897 while (bytes_left > CB_MAX_LENGTH) {
1898 status = ipw_fw_dma_add_command_block( priv,
1899 src_phys + src_offset,
1900 dest_address + dest_offset,
1901 CB_MAX_LENGTH, 0, 0);
1902 if (status) {
1903 IPW_DEBUG_FW_INFO(": Failed\n");
1904 return -1;
1905 } else
1906 IPW_DEBUG_FW_INFO(": Added new cb\n");
1907
1908 src_offset += CB_MAX_LENGTH;
1909 dest_offset += CB_MAX_LENGTH;
1910 bytes_left -= CB_MAX_LENGTH;
1911 }
1912
1913 /* add the buffer tail */
1914 if (bytes_left > 0) {
1915 status = ipw_fw_dma_add_command_block(
1916 priv, src_phys + src_offset,
1917 dest_address + dest_offset,
1918 bytes_left, 0, 0);
1919 if (status) {
1920 IPW_DEBUG_FW_INFO(": Failed on the buffer tail\n");
1921 return -1;
1922 } else
1923 IPW_DEBUG_FW_INFO(": Adding new cb - the buffer tail\n");
1924 }
1925
1926
1927 IPW_DEBUG_FW("<< \n");
1928 return 0;
1929}
1930
1931static int ipw_fw_dma_wait(struct ipw_priv *priv)
1932{
1933 u32 current_index = 0;
1934 u32 watchdog = 0;
1935
1936 IPW_DEBUG_FW(">> : \n");
1937
1938 current_index = ipw_fw_dma_command_block_index(priv);
1939 IPW_DEBUG_FW_INFO("sram_desc.last_cb_index:0x%8X\n",
1940 (int) priv->sram_desc.last_cb_index);
1941
1942 while (current_index < priv->sram_desc.last_cb_index) {
1943 udelay(50);
1944 current_index = ipw_fw_dma_command_block_index(priv);
1945
1946 watchdog++;
1947
1948 if (watchdog > 400) {
1949 IPW_DEBUG_FW_INFO("Timeout\n");
1950 ipw_fw_dma_dump_command_block(priv);
1951 ipw_fw_dma_abort(priv);
1952 return -1;
1953 }
1954 }
1955
1956 ipw_fw_dma_abort(priv);
1957
1958 /*Disable the DMA in the CSR register*/
1959 ipw_set_bit(priv, CX2_RESET_REG,
1960 CX2_RESET_REG_MASTER_DISABLED | CX2_RESET_REG_STOP_MASTER);
1961
1962 IPW_DEBUG_FW("<< dmaWaitSync \n");
1963 return 0;
1964}
1965
1966static void ipw_remove_current_network(struct ipw_priv *priv)
1967{
1968 struct list_head *element, *safe;
1969 struct ieee80211_network *network = NULL;
1970 list_for_each_safe(element, safe, &priv->ieee->network_list) {
1971 network = list_entry(element, struct ieee80211_network, list);
1972 if (!memcmp(network->bssid, priv->bssid, ETH_ALEN)) {
1973 list_del(element);
1974 list_add_tail(&network->list,
1975 &priv->ieee->network_free_list);
1976 }
1977 }
1978}
1979
1980/**
1981 * Check that card is still alive.
1982 * Reads debug register from domain0.
1983 * If card is present, pre-defined value should
1984 * be found there.
1985 *
1986 * @param priv
1987 * @return 1 if card is present, 0 otherwise
1988 */
1989static inline int ipw_alive(struct ipw_priv *priv)
1990{
1991 return ipw_read32(priv, 0x90) == 0xd55555d5;
1992}
1993
1994static inline int ipw_poll_bit(struct ipw_priv *priv, u32 addr, u32 mask,
1995 int timeout)
1996{
1997 int i = 0;
1998
1999 do {
2000 if ((ipw_read32(priv, addr) & mask) == mask)
2001 return i;
2002 mdelay(10);
2003 i += 10;
2004 } while (i < timeout);
2005
2006 return -ETIME;
2007}
2008
2009/* These functions load the firmware and micro code for the operation of
2010 * the ipw hardware. It assumes the buffer has all the bits for the
2011 * image and the caller is handling the memory allocation and clean up.
2012 */
2013
2014
2015static int ipw_stop_master(struct ipw_priv * priv)
2016{
2017 int rc;
2018
2019 IPW_DEBUG_TRACE(">> \n");
2020 /* stop master. typical delay - 0 */
2021 ipw_set_bit(priv, CX2_RESET_REG, CX2_RESET_REG_STOP_MASTER);
2022
2023 rc = ipw_poll_bit(priv, CX2_RESET_REG,
2024 CX2_RESET_REG_MASTER_DISABLED, 100);
2025 if (rc < 0) {
2026 IPW_ERROR("stop master failed in 10ms\n");
2027 return -1;
2028 }
2029
2030 IPW_DEBUG_INFO("stop master %dms\n", rc);
2031
2032 return rc;
2033}
2034
2035static void ipw_arc_release(struct ipw_priv *priv)
2036{
2037 IPW_DEBUG_TRACE(">> \n");
2038 mdelay(5);
2039
2040 ipw_clear_bit(priv, CX2_RESET_REG, CBD_RESET_REG_PRINCETON_RESET);
2041
2042 /* no one knows timing, for safety add some delay */
2043 mdelay(5);
2044}
2045
2046struct fw_header {
2047 u32 version;
2048 u32 mode;
2049};
2050
2051struct fw_chunk {
2052 u32 address;
2053 u32 length;
2054};
2055
2056#define IPW_FW_MAJOR_VERSION 2
2057#define IPW_FW_MINOR_VERSION 2
2058
2059#define IPW_FW_MINOR(x) ((x & 0xff) >> 8)
2060#define IPW_FW_MAJOR(x) (x & 0xff)
2061
2062#define IPW_FW_VERSION ((IPW_FW_MINOR_VERSION << 8) | \
2063 IPW_FW_MAJOR_VERSION)
2064
2065#define IPW_FW_PREFIX "ipw-" __stringify(IPW_FW_MAJOR_VERSION) \
2066"." __stringify(IPW_FW_MINOR_VERSION) "-"
2067
2068#if IPW_FW_MAJOR_VERSION >= 2 && IPW_FW_MINOR_VERSION > 0
2069#define IPW_FW_NAME(x) IPW_FW_PREFIX "" x ".fw"
2070#else
2071#define IPW_FW_NAME(x) "ipw2200_" x ".fw"
2072#endif
2073
2074static int ipw_load_ucode(struct ipw_priv *priv, u8 * data,
2075 size_t len)
2076{
2077 int rc = 0, i, addr;
2078 u8 cr = 0;
2079 u16 *image;
2080
2081 image = (u16 *)data;
2082
2083 IPW_DEBUG_TRACE(">> \n");
2084
2085 rc = ipw_stop_master(priv);
2086
2087 if (rc < 0)
2088 return rc;
2089
2090// spin_lock_irqsave(&priv->lock, flags);
2091
2092 for (addr = CX2_SHARED_LOWER_BOUND;
2093 addr < CX2_REGISTER_DOMAIN1_END; addr += 4) {
2094 ipw_write32(priv, addr, 0);
2095 }
2096
2097 /* no ucode (yet) */
2098 memset(&priv->dino_alive, 0, sizeof(priv->dino_alive));
2099 /* destroy DMA queues */
2100 /* reset sequence */
2101
2102 ipw_write_reg32(priv, CX2_MEM_HALT_AND_RESET ,CX2_BIT_HALT_RESET_ON);
2103 ipw_arc_release(priv);
2104 ipw_write_reg32(priv, CX2_MEM_HALT_AND_RESET, CX2_BIT_HALT_RESET_OFF);
2105 mdelay(1);
2106
2107 /* reset PHY */
2108 ipw_write_reg32(priv, CX2_INTERNAL_CMD_EVENT, CX2_BASEBAND_POWER_DOWN);
2109 mdelay(1);
2110
2111 ipw_write_reg32(priv, CX2_INTERNAL_CMD_EVENT, 0);
2112 mdelay(1);
2113
2114 /* enable ucode store */
2115 ipw_write_reg8(priv, DINO_CONTROL_REG, 0x0);
2116 ipw_write_reg8(priv, DINO_CONTROL_REG, DINO_ENABLE_CS);
2117 mdelay(1);
2118
2119 /* write ucode */
2120 /**
2121 * @bug
2122 * Do NOT set indirect address register once and then
2123 * store data to indirect data register in the loop.
2124 * It seems very reasonable, but in this case DINO do not
2125 * accept ucode. It is essential to set address each time.
2126 */
2127 /* load new ipw uCode */
2128 for (i = 0; i < len / 2; i++)
2129 ipw_write_reg16(priv, CX2_BASEBAND_CONTROL_STORE, image[i]);
2130
2131
2132 /* enable DINO */
2133 ipw_write_reg8(priv, CX2_BASEBAND_CONTROL_STATUS, 0);
2134 ipw_write_reg8(priv, CX2_BASEBAND_CONTROL_STATUS,
2135 DINO_ENABLE_SYSTEM );
2136
2137 /* this is where the igx / win driver deveates from the VAP driver.*/
2138
2139 /* wait for alive response */
2140 for (i = 0; i < 100; i++) {
2141 /* poll for incoming data */
2142 cr = ipw_read_reg8(priv, CX2_BASEBAND_CONTROL_STATUS);
2143 if (cr & DINO_RXFIFO_DATA)
2144 break;
2145 mdelay(1);
2146 }
2147
2148 if (cr & DINO_RXFIFO_DATA) {
2149 /* alive_command_responce size is NOT multiple of 4 */
2150 u32 response_buffer[(sizeof(priv->dino_alive) + 3) / 4];
2151
2152 for (i = 0; i < ARRAY_SIZE(response_buffer); i++)
2153 response_buffer[i] =
2154 ipw_read_reg32(priv,
2155 CX2_BASEBAND_RX_FIFO_READ);
2156 memcpy(&priv->dino_alive, response_buffer,
2157 sizeof(priv->dino_alive));
2158 if (priv->dino_alive.alive_command == 1
2159 && priv->dino_alive.ucode_valid == 1) {
2160 rc = 0;
2161 IPW_DEBUG_INFO(
2162 "Microcode OK, rev. %d (0x%x) dev. %d (0x%x) "
2163 "of %02d/%02d/%02d %02d:%02d\n",
2164 priv->dino_alive.software_revision,
2165 priv->dino_alive.software_revision,
2166 priv->dino_alive.device_identifier,
2167 priv->dino_alive.device_identifier,
2168 priv->dino_alive.time_stamp[0],
2169 priv->dino_alive.time_stamp[1],
2170 priv->dino_alive.time_stamp[2],
2171 priv->dino_alive.time_stamp[3],
2172 priv->dino_alive.time_stamp[4]);
2173 } else {
2174 IPW_DEBUG_INFO("Microcode is not alive\n");
2175 rc = -EINVAL;
2176 }
2177 } else {
2178 IPW_DEBUG_INFO("No alive response from DINO\n");
2179 rc = -ETIME;
2180 }
2181
2182 /* disable DINO, otherwise for some reason
2183 firmware have problem getting alive resp. */
2184 ipw_write_reg8(priv, CX2_BASEBAND_CONTROL_STATUS, 0);
2185
2186// spin_unlock_irqrestore(&priv->lock, flags);
2187
2188 return rc;
2189}
2190
2191static int ipw_load_firmware(struct ipw_priv *priv, u8 * data,
2192 size_t len)
2193{
2194 int rc = -1;
2195 int offset = 0;
2196 struct fw_chunk *chunk;
2197 dma_addr_t shared_phys;
2198 u8 *shared_virt;
2199
2200 IPW_DEBUG_TRACE("<< : \n");
2201 shared_virt = pci_alloc_consistent(priv->pci_dev, len, &shared_phys);
2202
2203 if (!shared_virt)
2204 return -ENOMEM;
2205
2206 memmove(shared_virt, data, len);
2207
2208 /* Start the Dma */
2209 rc = ipw_fw_dma_enable(priv);
2210
2211 if (priv->sram_desc.last_cb_index > 0) {
2212 /* the DMA is already ready this would be a bug. */
2213 BUG();
2214 goto out;
2215 }
2216
2217 do {
2218 chunk = (struct fw_chunk *)(data + offset);
2219 offset += sizeof(struct fw_chunk);
2220 /* build DMA packet and queue up for sending */
2221 /* dma to chunk->address, the chunk->length bytes from data +
2222 * offeset*/
2223 /* Dma loading */
2224 rc = ipw_fw_dma_add_buffer(priv, shared_phys + offset,
2225 chunk->address, chunk->length);
2226 if (rc) {
2227 IPW_DEBUG_INFO("dmaAddBuffer Failed\n");
2228 goto out;
2229 }
2230
2231 offset += chunk->length;
2232 } while (offset < len);
2233
2234 /* Run the DMA and wait for the answer*/
2235 rc = ipw_fw_dma_kick(priv);
2236 if (rc) {
2237 IPW_ERROR("dmaKick Failed\n");
2238 goto out;
2239 }
2240
2241 rc = ipw_fw_dma_wait(priv);
2242 if (rc) {
2243 IPW_ERROR("dmaWaitSync Failed\n");
2244 goto out;
2245 }
2246 out:
2247 pci_free_consistent( priv->pci_dev, len, shared_virt, shared_phys);
2248 return rc;
2249}
2250
2251/* stop nic */
2252static int ipw_stop_nic(struct ipw_priv *priv)
2253{
2254 int rc = 0;
2255
2256 /* stop*/
2257 ipw_write32(priv, CX2_RESET_REG, CX2_RESET_REG_STOP_MASTER);
2258
2259 rc = ipw_poll_bit(priv, CX2_RESET_REG,
2260 CX2_RESET_REG_MASTER_DISABLED, 500);
2261 if (rc < 0) {
2262 IPW_ERROR("wait for reg master disabled failed\n");
2263 return rc;
2264 }
2265
2266 ipw_set_bit(priv, CX2_RESET_REG, CBD_RESET_REG_PRINCETON_RESET);
2267
2268 return rc;
2269}
2270
2271static void ipw_start_nic(struct ipw_priv *priv)
2272{
2273 IPW_DEBUG_TRACE(">>\n");
2274
2275 /* prvHwStartNic release ARC*/
2276 ipw_clear_bit(priv, CX2_RESET_REG,
2277 CX2_RESET_REG_MASTER_DISABLED |
2278 CX2_RESET_REG_STOP_MASTER |
2279 CBD_RESET_REG_PRINCETON_RESET);
2280
2281 /* enable power management */
2282 ipw_set_bit(priv, CX2_GP_CNTRL_RW, CX2_GP_CNTRL_BIT_HOST_ALLOWS_STANDBY);
2283
2284 IPW_DEBUG_TRACE("<<\n");
2285}
2286
2287static int ipw_init_nic(struct ipw_priv *priv)
2288{
2289 int rc;
2290
2291 IPW_DEBUG_TRACE(">>\n");
2292 /* reset */
2293 /*prvHwInitNic */
2294 /* set "initialization complete" bit to move adapter to D0 state */
2295 ipw_set_bit(priv, CX2_GP_CNTRL_RW, CX2_GP_CNTRL_BIT_INIT_DONE);
2296
2297 /* low-level PLL activation */
2298 ipw_write32(priv, CX2_READ_INT_REGISTER, CX2_BIT_INT_HOST_SRAM_READ_INT_REGISTER);
2299
2300 /* wait for clock stabilization */
2301 rc = ipw_poll_bit(priv, CX2_GP_CNTRL_RW,
2302 CX2_GP_CNTRL_BIT_CLOCK_READY, 250);
2303 if (rc < 0 )
2304 IPW_DEBUG_INFO("FAILED wait for clock stablization\n");
2305
2306 /* assert SW reset */
2307 ipw_set_bit(priv, CX2_RESET_REG, CX2_RESET_REG_SW_RESET);
2308
2309 udelay(10);
2310
2311 /* set "initialization complete" bit to move adapter to D0 state */
2312 ipw_set_bit(priv, CX2_GP_CNTRL_RW, CX2_GP_CNTRL_BIT_INIT_DONE);
2313
2314 IPW_DEBUG_TRACE(">>\n");
2315 return 0;
2316}
2317
2318
2319/* Call this function from process context, it will sleep in request_firmware.
2320 * Probe is an ok place to call this from.
2321 */
2322static int ipw_reset_nic(struct ipw_priv *priv)
2323{
2324 int rc = 0;
2325
2326 IPW_DEBUG_TRACE(">>\n");
2327
2328 rc = ipw_init_nic(priv);
2329
2330 /* Clear the 'host command active' bit... */
2331 priv->status &= ~STATUS_HCMD_ACTIVE;
2332 wake_up_interruptible(&priv->wait_command_queue);
2333
2334 IPW_DEBUG_TRACE("<<\n");
2335 return rc;
2336}
2337
2338static int ipw_get_fw(struct ipw_priv *priv,
2339 const struct firmware **fw, const char *name)
2340{
2341 struct fw_header *header;
2342 int rc;
2343
2344 /* ask firmware_class module to get the boot firmware off disk */
2345 rc = request_firmware(fw, name, &priv->pci_dev->dev);
2346 if (rc < 0) {
2347 IPW_ERROR("%s load failed: Reason %d\n", name, rc);
2348 return rc;
2349 }
2350
2351 header = (struct fw_header *)(*fw)->data;
2352 if (IPW_FW_MAJOR(header->version) != IPW_FW_MAJOR_VERSION) {
2353 IPW_ERROR("'%s' firmware version not compatible (%d != %d)\n",
2354 name,
2355 IPW_FW_MAJOR(header->version), IPW_FW_MAJOR_VERSION);
2356 return -EINVAL;
2357 }
2358
2359 IPW_DEBUG_INFO("Loading firmware '%s' file v%d.%d (%zd bytes)\n",
2360 name,
2361 IPW_FW_MAJOR(header->version),
2362 IPW_FW_MINOR(header->version),
2363 (*fw)->size - sizeof(struct fw_header));
2364 return 0;
2365}
2366
2367#define CX2_RX_BUF_SIZE (3000)
2368
2369static inline void ipw_rx_queue_reset(struct ipw_priv *priv,
2370 struct ipw_rx_queue *rxq)
2371{
2372 unsigned long flags;
2373 int i;
2374
2375 spin_lock_irqsave(&rxq->lock, flags);
2376
2377 INIT_LIST_HEAD(&rxq->rx_free);
2378 INIT_LIST_HEAD(&rxq->rx_used);
2379
2380 /* Fill the rx_used queue with _all_ of the Rx buffers */
2381 for (i = 0; i < RX_FREE_BUFFERS + RX_QUEUE_SIZE; i++) {
2382 /* In the reset function, these buffers may have been allocated
2383 * to an SKB, so we need to unmap and free potential storage */
2384 if (rxq->pool[i].skb != NULL) {
2385 pci_unmap_single(priv->pci_dev, rxq->pool[i].dma_addr,
2386 CX2_RX_BUF_SIZE,
2387 PCI_DMA_FROMDEVICE);
2388 dev_kfree_skb(rxq->pool[i].skb);
2389 }
2390 list_add_tail(&rxq->pool[i].list, &rxq->rx_used);
2391 }
2392
2393 /* Set us so that we have processed and used all buffers, but have
2394 * not restocked the Rx queue with fresh buffers */
2395 rxq->read = rxq->write = 0;
2396 rxq->processed = RX_QUEUE_SIZE - 1;
2397 rxq->free_count = 0;
2398 spin_unlock_irqrestore(&rxq->lock, flags);
2399}
2400
2401#ifdef CONFIG_PM
2402static int fw_loaded = 0;
2403static const struct firmware *bootfw = NULL;
2404static const struct firmware *firmware = NULL;
2405static const struct firmware *ucode = NULL;
2406#endif
2407
2408static int ipw_load(struct ipw_priv *priv)
2409{
2410#ifndef CONFIG_PM
2411 const struct firmware *bootfw = NULL;
2412 const struct firmware *firmware = NULL;
2413 const struct firmware *ucode = NULL;
2414#endif
2415 int rc = 0, retries = 3;
2416
2417#ifdef CONFIG_PM
2418 if (!fw_loaded) {
2419#endif
2420 rc = ipw_get_fw(priv, &bootfw, IPW_FW_NAME("boot"));
2421 if (rc)
2422 goto error;
2423
2424 switch (priv->ieee->iw_mode) {
2425 case IW_MODE_ADHOC:
2426 rc = ipw_get_fw(priv, &ucode,
2427 IPW_FW_NAME("ibss_ucode"));
2428 if (rc)
2429 goto error;
2430
2431 rc = ipw_get_fw(priv, &firmware, IPW_FW_NAME("ibss"));
2432 break;
2433
2434#ifdef CONFIG_IPW_PROMISC
2435 case IW_MODE_MONITOR:
2436 rc = ipw_get_fw(priv, &ucode,
2437 IPW_FW_NAME("ibss_ucode"));
2438 if (rc)
2439 goto error;
2440
2441 rc = ipw_get_fw(priv, &firmware, IPW_FW_NAME("sniffer"));
2442 break;
2443#endif
2444 case IW_MODE_INFRA:
2445 rc = ipw_get_fw(priv, &ucode,
2446 IPW_FW_NAME("bss_ucode"));
2447 if (rc)
2448 goto error;
2449
2450 rc = ipw_get_fw(priv, &firmware, IPW_FW_NAME("bss"));
2451 break;
2452
2453 default:
2454 rc = -EINVAL;
2455 }
2456
2457 if (rc)
2458 goto error;
2459
2460#ifdef CONFIG_PM
2461 fw_loaded = 1;
2462 }
2463#endif
2464
2465 if (!priv->rxq)
2466 priv->rxq = ipw_rx_queue_alloc(priv);
2467 else
2468 ipw_rx_queue_reset(priv, priv->rxq);
2469 if (!priv->rxq) {
2470 IPW_ERROR("Unable to initialize Rx queue\n");
2471 goto error;
2472 }
2473
2474 retry:
2475 /* Ensure interrupts are disabled */
2476 ipw_write32(priv, CX2_INTA_MASK_R, ~CX2_INTA_MASK_ALL);
2477 priv->status &= ~STATUS_INT_ENABLED;
2478
2479 /* ack pending interrupts */
2480 ipw_write32(priv, CX2_INTA_RW, CX2_INTA_MASK_ALL);
2481
2482 ipw_stop_nic(priv);
2483
2484 rc = ipw_reset_nic(priv);
2485 if (rc) {
2486 IPW_ERROR("Unable to reset NIC\n");
2487 goto error;
2488 }
2489
2490 ipw_zero_memory(priv, CX2_NIC_SRAM_LOWER_BOUND,
2491 CX2_NIC_SRAM_UPPER_BOUND - CX2_NIC_SRAM_LOWER_BOUND);
2492
2493 /* DMA the initial boot firmware into the device */
2494 rc = ipw_load_firmware(priv, bootfw->data + sizeof(struct fw_header),
2495 bootfw->size - sizeof(struct fw_header));
2496 if (rc < 0) {
2497 IPW_ERROR("Unable to load boot firmware\n");
2498 goto error;
2499 }
2500
2501 /* kick start the device */
2502 ipw_start_nic(priv);
2503
2504 /* wait for the device to finish it's initial startup sequence */
2505 rc = ipw_poll_bit(priv, CX2_INTA_RW,
2506 CX2_INTA_BIT_FW_INITIALIZATION_DONE, 500);
2507 if (rc < 0) {
2508 IPW_ERROR("device failed to boot initial fw image\n");
2509 goto error;
2510 }
2511 IPW_DEBUG_INFO("initial device response after %dms\n", rc);
2512
2513 /* ack fw init done interrupt */
2514 ipw_write32(priv, CX2_INTA_RW, CX2_INTA_BIT_FW_INITIALIZATION_DONE);
2515
2516 /* DMA the ucode into the device */
2517 rc = ipw_load_ucode(priv, ucode->data + sizeof(struct fw_header),
2518 ucode->size - sizeof(struct fw_header));
2519 if (rc < 0) {
2520 IPW_ERROR("Unable to load ucode\n");
2521 goto error;
2522 }
2523
2524 /* stop nic */
2525 ipw_stop_nic(priv);
2526
2527 /* DMA bss firmware into the device */
2528 rc = ipw_load_firmware(priv, firmware->data +
2529 sizeof(struct fw_header),
2530 firmware->size - sizeof(struct fw_header));
2531 if (rc < 0 ) {
2532 IPW_ERROR("Unable to load firmware\n");
2533 goto error;
2534 }
2535
2536 ipw_write32(priv, IPW_EEPROM_LOAD_DISABLE, 0);
2537
2538 rc = ipw_queue_reset(priv);
2539 if (rc) {
2540 IPW_ERROR("Unable to initialize queues\n");
2541 goto error;
2542 }
2543
2544 /* Ensure interrupts are disabled */
2545 ipw_write32(priv, CX2_INTA_MASK_R, ~CX2_INTA_MASK_ALL);
2546
2547 /* kick start the device */
2548 ipw_start_nic(priv);
2549
2550 if (ipw_read32(priv, CX2_INTA_RW) & CX2_INTA_BIT_PARITY_ERROR) {
2551 if (retries > 0) {
2552 IPW_WARNING("Parity error. Retrying init.\n");
2553 retries--;
2554 goto retry;
2555 }
2556
2557 IPW_ERROR("TODO: Handle parity error -- schedule restart?\n");
2558 rc = -EIO;
2559 goto error;
2560 }
2561
2562 /* wait for the device */
2563 rc = ipw_poll_bit(priv, CX2_INTA_RW,
2564 CX2_INTA_BIT_FW_INITIALIZATION_DONE, 500);
2565 if (rc < 0) {
2566 IPW_ERROR("device failed to start after 500ms\n");
2567 goto error;
2568 }
2569 IPW_DEBUG_INFO("device response after %dms\n", rc);
2570
2571 /* ack fw init done interrupt */
2572 ipw_write32(priv, CX2_INTA_RW, CX2_INTA_BIT_FW_INITIALIZATION_DONE);
2573
2574 /* read eeprom data and initialize the eeprom region of sram */
2575 priv->eeprom_delay = 1;
2576 ipw_eeprom_init_sram(priv);
2577
2578 /* enable interrupts */
2579 ipw_enable_interrupts(priv);
2580
2581 /* Ensure our queue has valid packets */
2582 ipw_rx_queue_replenish(priv);
2583
2584 ipw_write32(priv, CX2_RX_READ_INDEX, priv->rxq->read);
2585
2586 /* ack pending interrupts */
2587 ipw_write32(priv, CX2_INTA_RW, CX2_INTA_MASK_ALL);
2588
2589#ifndef CONFIG_PM
2590 release_firmware(bootfw);
2591 release_firmware(ucode);
2592 release_firmware(firmware);
2593#endif
2594 return 0;
2595
2596 error:
2597 if (priv->rxq) {
2598 ipw_rx_queue_free(priv, priv->rxq);
2599 priv->rxq = NULL;
2600 }
2601 ipw_tx_queue_free(priv);
2602 if (bootfw)
2603 release_firmware(bootfw);
2604 if (ucode)
2605 release_firmware(ucode);
2606 if (firmware)
2607 release_firmware(firmware);
2608#ifdef CONFIG_PM
2609 fw_loaded = 0;
2610 bootfw = ucode = firmware = NULL;
2611#endif
2612
2613 return rc;
2614}
2615
2616/**
2617 * DMA services
2618 *
2619 * Theory of operation
2620 *
2621 * A queue is a circular buffers with 'Read' and 'Write' pointers.
2622 * 2 empty entries always kept in the buffer to protect from overflow.
2623 *
2624 * For Tx queue, there are low mark and high mark limits. If, after queuing
2625 * the packet for Tx, free space become < low mark, Tx queue stopped. When
2626 * reclaiming packets (on 'tx done IRQ), if free space become > high mark,
2627 * Tx queue resumed.
2628 *
2629 * The IPW operates with six queues, one receive queue in the device's
2630 * sram, one transmit queue for sending commands to the device firmware,
2631 * and four transmit queues for data.
2632 *
2633 * The four transmit queues allow for performing quality of service (qos)
2634 * transmissions as per the 802.11 protocol. Currently Linux does not
2635 * provide a mechanism to the user for utilizing prioritized queues, so
2636 * we only utilize the first data transmit queue (queue1).
2637 */
2638
2639/**
2640 * Driver allocates buffers of this size for Rx
2641 */
2642
2643static inline int ipw_queue_space(const struct clx2_queue *q)
2644{
2645 int s = q->last_used - q->first_empty;
2646 if (s <= 0)
2647 s += q->n_bd;
2648 s -= 2; /* keep some reserve to not confuse empty and full situations */
2649 if (s < 0)
2650 s = 0;
2651 return s;
2652}
2653
2654static inline int ipw_queue_inc_wrap(int index, int n_bd)
2655{
2656 return (++index == n_bd) ? 0 : index;
2657}
2658
2659/**
2660 * Initialize common DMA queue structure
2661 *
2662 * @param q queue to init
2663 * @param count Number of BD's to allocate. Should be power of 2
2664 * @param read_register Address for 'read' register
2665 * (not offset within BAR, full address)
2666 * @param write_register Address for 'write' register
2667 * (not offset within BAR, full address)
2668 * @param base_register Address for 'base' register
2669 * (not offset within BAR, full address)
2670 * @param size Address for 'size' register
2671 * (not offset within BAR, full address)
2672 */
2673static void ipw_queue_init(struct ipw_priv *priv, struct clx2_queue *q,
2674 int count, u32 read, u32 write,
2675 u32 base, u32 size)
2676{
2677 q->n_bd = count;
2678
2679 q->low_mark = q->n_bd / 4;
2680 if (q->low_mark < 4)
2681 q->low_mark = 4;
2682
2683 q->high_mark = q->n_bd / 8;
2684 if (q->high_mark < 2)
2685 q->high_mark = 2;
2686
2687 q->first_empty = q->last_used = 0;
2688 q->reg_r = read;
2689 q->reg_w = write;
2690
2691 ipw_write32(priv, base, q->dma_addr);
2692 ipw_write32(priv, size, count);
2693 ipw_write32(priv, read, 0);
2694 ipw_write32(priv, write, 0);
2695
2696 _ipw_read32(priv, 0x90);
2697}
2698
2699static int ipw_queue_tx_init(struct ipw_priv *priv,
2700 struct clx2_tx_queue *q,
2701 int count, u32 read, u32 write,
2702 u32 base, u32 size)
2703{
2704 struct pci_dev *dev = priv->pci_dev;
2705
2706 q->txb = kmalloc(sizeof(q->txb[0]) * count, GFP_KERNEL);
2707 if (!q->txb) {
2708 IPW_ERROR("vmalloc for auxilary BD structures failed\n");
2709 return -ENOMEM;
2710 }
2711
2712 q->bd = pci_alloc_consistent(dev,sizeof(q->bd[0])*count, &q->q.dma_addr);
2713 if (!q->bd) {
2714 IPW_ERROR("pci_alloc_consistent(%zd) failed\n",
2715 sizeof(q->bd[0]) * count);
2716 kfree(q->txb);
2717 q->txb = NULL;
2718 return -ENOMEM;
2719 }
2720
2721 ipw_queue_init(priv, &q->q, count, read, write, base, size);
2722 return 0;
2723}
2724
2725/**
2726 * Free one TFD, those at index [txq->q.last_used].
2727 * Do NOT advance any indexes
2728 *
2729 * @param dev
2730 * @param txq
2731 */
2732static void ipw_queue_tx_free_tfd(struct ipw_priv *priv,
2733 struct clx2_tx_queue *txq)
2734{
2735 struct tfd_frame *bd = &txq->bd[txq->q.last_used];
2736 struct pci_dev *dev = priv->pci_dev;
2737 int i;
2738
2739 /* classify bd */
2740 if (bd->control_flags.message_type == TX_HOST_COMMAND_TYPE)
2741 /* nothing to cleanup after for host commands */
2742 return;
2743
2744 /* sanity check */
2745 if (bd->u.data.num_chunks > NUM_TFD_CHUNKS) {
2746 IPW_ERROR("Too many chunks: %i\n", bd->u.data.num_chunks);
2747 /** @todo issue fatal error, it is quite serious situation */
2748 return;
2749 }
2750
2751 /* unmap chunks if any */
2752 for (i = 0; i < bd->u.data.num_chunks; i++) {
2753 pci_unmap_single(dev, bd->u.data.chunk_ptr[i],
2754 bd->u.data.chunk_len[i], PCI_DMA_TODEVICE);
2755 if (txq->txb[txq->q.last_used]) {
2756 ieee80211_txb_free(txq->txb[txq->q.last_used]);
2757 txq->txb[txq->q.last_used] = NULL;
2758 }
2759 }
2760}
2761
2762/**
2763 * Deallocate DMA queue.
2764 *
2765 * Empty queue by removing and destroying all BD's.
2766 * Free all buffers.
2767 *
2768 * @param dev
2769 * @param q
2770 */
2771static void ipw_queue_tx_free(struct ipw_priv *priv,
2772 struct clx2_tx_queue *txq)
2773{
2774 struct clx2_queue *q = &txq->q;
2775 struct pci_dev *dev = priv->pci_dev;
2776
2777 if (q->n_bd == 0)
2778 return;
2779
2780 /* first, empty all BD's */
2781 for (; q->first_empty != q->last_used;
2782 q->last_used = ipw_queue_inc_wrap(q->last_used, q->n_bd)) {
2783 ipw_queue_tx_free_tfd(priv, txq);
2784 }
2785
2786 /* free buffers belonging to queue itself */
2787 pci_free_consistent(dev, sizeof(txq->bd[0])*q->n_bd, txq->bd,
2788 q->dma_addr);
2789 kfree(txq->txb);
2790
2791 /* 0 fill whole structure */
2792 memset(txq, 0, sizeof(*txq));
2793}
2794
2795
2796/**
2797 * Destroy all DMA queues and structures
2798 *
2799 * @param priv
2800 */
2801static void ipw_tx_queue_free(struct ipw_priv *priv)
2802{
2803 /* Tx CMD queue */
2804 ipw_queue_tx_free(priv, &priv->txq_cmd);
2805
2806 /* Tx queues */
2807 ipw_queue_tx_free(priv, &priv->txq[0]);
2808 ipw_queue_tx_free(priv, &priv->txq[1]);
2809 ipw_queue_tx_free(priv, &priv->txq[2]);
2810 ipw_queue_tx_free(priv, &priv->txq[3]);
2811}
2812
2813static void inline __maybe_wake_tx(struct ipw_priv *priv)
2814{
2815 if (netif_running(priv->net_dev)) {
2816 switch (priv->port_type) {
2817 case DCR_TYPE_MU_BSS:
2818 case DCR_TYPE_MU_IBSS:
2819 if (!(priv->status & STATUS_ASSOCIATED)) {
2820 return;
2821 }
2822 }
2823 netif_wake_queue(priv->net_dev);
2824 }
2825
2826}
2827
2828static inline void ipw_create_bssid(struct ipw_priv *priv, u8 *bssid)
2829{
2830 /* First 3 bytes are manufacturer */
2831 bssid[0] = priv->mac_addr[0];
2832 bssid[1] = priv->mac_addr[1];
2833 bssid[2] = priv->mac_addr[2];
2834
2835 /* Last bytes are random */
2836 get_random_bytes(&bssid[3], ETH_ALEN-3);
2837
2838 bssid[0] &= 0xfe; /* clear multicast bit */
2839 bssid[0] |= 0x02; /* set local assignment bit (IEEE802) */
2840}
2841
2842static inline u8 ipw_add_station(struct ipw_priv *priv, u8 *bssid)
2843{
2844 struct ipw_station_entry entry;
2845 int i;
2846
2847 for (i = 0; i < priv->num_stations; i++) {
2848 if (!memcmp(priv->stations[i], bssid, ETH_ALEN)) {
2849 /* Another node is active in network */
2850 priv->missed_adhoc_beacons = 0;
2851 if (!(priv->config & CFG_STATIC_CHANNEL))
2852 /* when other nodes drop out, we drop out */
2853 priv->config &= ~CFG_ADHOC_PERSIST;
2854
2855 return i;
2856 }
2857 }
2858
2859 if (i == MAX_STATIONS)
2860 return IPW_INVALID_STATION;
2861
2862 IPW_DEBUG_SCAN("Adding AdHoc station: " MAC_FMT "\n", MAC_ARG(bssid));
2863
2864 entry.reserved = 0;
2865 entry.support_mode = 0;
2866 memcpy(entry.mac_addr, bssid, ETH_ALEN);
2867 memcpy(priv->stations[i], bssid, ETH_ALEN);
2868 ipw_write_direct(priv, IPW_STATION_TABLE_LOWER + i * sizeof(entry),
2869 &entry,
2870 sizeof(entry));
2871 priv->num_stations++;
2872
2873 return i;
2874}
2875
2876static inline u8 ipw_find_station(struct ipw_priv *priv, u8 *bssid)
2877{
2878 int i;
2879
2880 for (i = 0; i < priv->num_stations; i++)
2881 if (!memcmp(priv->stations[i], bssid, ETH_ALEN))
2882 return i;
2883
2884 return IPW_INVALID_STATION;
2885}
2886
2887static void ipw_send_disassociate(struct ipw_priv *priv, int quiet)
2888{
2889 int err;
2890
2891 if (!(priv->status & (STATUS_ASSOCIATING | STATUS_ASSOCIATED))) {
2892 IPW_DEBUG_ASSOC("Disassociating while not associated.\n");
2893 return;
2894 }
2895
2896 IPW_DEBUG_ASSOC("Disassocation attempt from " MAC_FMT " "
2897 "on channel %d.\n",
2898 MAC_ARG(priv->assoc_request.bssid),
2899 priv->assoc_request.channel);
2900
2901 priv->status &= ~(STATUS_ASSOCIATING | STATUS_ASSOCIATED);
2902 priv->status |= STATUS_DISASSOCIATING;
2903
2904 if (quiet)
2905 priv->assoc_request.assoc_type = HC_DISASSOC_QUIET;
2906 else
2907 priv->assoc_request.assoc_type = HC_DISASSOCIATE;
2908 err = ipw_send_associate(priv, &priv->assoc_request);
2909 if (err) {
2910 IPW_DEBUG_HC("Attempt to send [dis]associate command "
2911 "failed.\n");
2912 return;
2913 }
2914
2915}
2916
2917static void ipw_disassociate(void *data)
2918{
2919 ipw_send_disassociate(data, 0);
2920}
2921
2922static void notify_wx_assoc_event(struct ipw_priv *priv)
2923{
2924 union iwreq_data wrqu;
2925 wrqu.ap_addr.sa_family = ARPHRD_ETHER;
2926 if (priv->status & STATUS_ASSOCIATED)
2927 memcpy(wrqu.ap_addr.sa_data, priv->bssid, ETH_ALEN);
2928 else
2929 memset(wrqu.ap_addr.sa_data, 0, ETH_ALEN);
2930 wireless_send_event(priv->net_dev, SIOCGIWAP, &wrqu, NULL);
2931}
2932
2933struct ipw_status_code {
2934 u16 status;
2935 const char *reason;
2936};
2937
2938static const struct ipw_status_code ipw_status_codes[] = {
2939 {0x00, "Successful"},
2940 {0x01, "Unspecified failure"},
2941 {0x0A, "Cannot support all requested capabilities in the "
2942 "Capability information field"},
2943 {0x0B, "Reassociation denied due to inability to confirm that "
2944 "association exists"},
2945 {0x0C, "Association denied due to reason outside the scope of this "
2946 "standard"},
2947 {0x0D, "Responding station does not support the specified authentication "
2948 "algorithm"},
2949 {0x0E, "Received an Authentication frame with authentication sequence "
2950 "transaction sequence number out of expected sequence"},
2951 {0x0F, "Authentication rejected because of challenge failure"},
2952 {0x10, "Authentication rejected due to timeout waiting for next "
2953 "frame in sequence"},
2954 {0x11, "Association denied because AP is unable to handle additional "
2955 "associated stations"},
2956 {0x12, "Association denied due to requesting station not supporting all "
2957 "of the datarates in the BSSBasicServiceSet Parameter"},
2958 {0x13, "Association denied due to requesting station not supporting "
2959 "short preamble operation"},
2960 {0x14, "Association denied due to requesting station not supporting "
2961 "PBCC encoding"},
2962 {0x15, "Association denied due to requesting station not supporting "
2963 "channel agility"},
2964 {0x19, "Association denied due to requesting station not supporting "
2965 "short slot operation"},
2966 {0x1A, "Association denied due to requesting station not supporting "
2967 "DSSS-OFDM operation"},
2968 {0x28, "Invalid Information Element"},
2969 {0x29, "Group Cipher is not valid"},
2970 {0x2A, "Pairwise Cipher is not valid"},
2971 {0x2B, "AKMP is not valid"},
2972 {0x2C, "Unsupported RSN IE version"},
2973 {0x2D, "Invalid RSN IE Capabilities"},
2974 {0x2E, "Cipher suite is rejected per security policy"},
2975};
2976
2977#ifdef CONFIG_IPW_DEBUG
2978static const char *ipw_get_status_code(u16 status)
2979{
2980 int i;
2981 for (i = 0; i < ARRAY_SIZE(ipw_status_codes); i++)
2982 if (ipw_status_codes[i].status == status)
2983 return ipw_status_codes[i].reason;
2984 return "Unknown status value.";
2985}
2986#endif
2987
2988static void inline average_init(struct average *avg)
2989{
2990 memset(avg, 0, sizeof(*avg));
2991}
2992
2993static void inline average_add(struct average *avg, s16 val)
2994{
2995 avg->sum -= avg->entries[avg->pos];
2996 avg->sum += val;
2997 avg->entries[avg->pos++] = val;
2998 if (unlikely(avg->pos == AVG_ENTRIES)) {
2999 avg->init = 1;
3000 avg->pos = 0;
3001 }
3002}
3003
3004static s16 inline average_value(struct average *avg)
3005{
3006 if (!unlikely(avg->init)) {
3007 if (avg->pos)
3008 return avg->sum / avg->pos;
3009 return 0;
3010 }
3011
3012 return avg->sum / AVG_ENTRIES;
3013}
3014
3015static void ipw_reset_stats(struct ipw_priv *priv)
3016{
3017 u32 len = sizeof(u32);
3018
3019 priv->quality = 0;
3020
3021 average_init(&priv->average_missed_beacons);
3022 average_init(&priv->average_rssi);
3023 average_init(&priv->average_noise);
3024
3025 priv->last_rate = 0;
3026 priv->last_missed_beacons = 0;
3027 priv->last_rx_packets = 0;
3028 priv->last_tx_packets = 0;
3029 priv->last_tx_failures = 0;
3030
3031 /* Firmware managed, reset only when NIC is restarted, so we have to
3032 * normalize on the current value */
3033 ipw_get_ordinal(priv, IPW_ORD_STAT_RX_ERR_CRC,
3034 &priv->last_rx_err, &len);
3035 ipw_get_ordinal(priv, IPW_ORD_STAT_TX_FAILURE,
3036 &priv->last_tx_failures, &len);
3037
3038 /* Driver managed, reset with each association */
3039 priv->missed_adhoc_beacons = 0;
3040 priv->missed_beacons = 0;
3041 priv->tx_packets = 0;
3042 priv->rx_packets = 0;
3043
3044}
3045
3046
3047static inline u32 ipw_get_max_rate(struct ipw_priv *priv)
3048{
3049 u32 i = 0x80000000;
3050 u32 mask = priv->rates_mask;
3051 /* If currently associated in B mode, restrict the maximum
3052 * rate match to B rates */
3053 if (priv->assoc_request.ieee_mode == IPW_B_MODE)
3054 mask &= IEEE80211_CCK_RATES_MASK;
3055
3056 /* TODO: Verify that the rate is supported by the current rates
3057 * list. */
3058
3059 while (i && !(mask & i)) i >>= 1;
3060 switch (i) {
3061 case IEEE80211_CCK_RATE_1MB_MASK: return 1000000;
3062 case IEEE80211_CCK_RATE_2MB_MASK: return 2000000;
3063 case IEEE80211_CCK_RATE_5MB_MASK: return 5500000;
3064 case IEEE80211_OFDM_RATE_6MB_MASK: return 6000000;
3065 case IEEE80211_OFDM_RATE_9MB_MASK: return 9000000;
3066 case IEEE80211_CCK_RATE_11MB_MASK: return 11000000;
3067 case IEEE80211_OFDM_RATE_12MB_MASK: return 12000000;
3068 case IEEE80211_OFDM_RATE_18MB_MASK: return 18000000;
3069 case IEEE80211_OFDM_RATE_24MB_MASK: return 24000000;
3070 case IEEE80211_OFDM_RATE_36MB_MASK: return 36000000;
3071 case IEEE80211_OFDM_RATE_48MB_MASK: return 48000000;
3072 case IEEE80211_OFDM_RATE_54MB_MASK: return 54000000;
3073 }
3074
3075 if (priv->ieee->mode == IEEE_B)
3076 return 11000000;
3077 else
3078 return 54000000;
3079}
3080
3081static u32 ipw_get_current_rate(struct ipw_priv *priv)
3082{
3083 u32 rate, len = sizeof(rate);
3084 int err;
3085
3086 if (!(priv->status & STATUS_ASSOCIATED))
3087 return 0;
3088
3089 if (priv->tx_packets > IPW_REAL_RATE_RX_PACKET_THRESHOLD) {
3090 err = ipw_get_ordinal(priv, IPW_ORD_STAT_TX_CURR_RATE, &rate,
3091 &len);
3092 if (err) {
3093 IPW_DEBUG_INFO("failed querying ordinals.\n");
3094 return 0;
3095 }
3096 } else
3097 return ipw_get_max_rate(priv);
3098
3099 switch (rate) {
3100 case IPW_TX_RATE_1MB: return 1000000;
3101 case IPW_TX_RATE_2MB: return 2000000;
3102 case IPW_TX_RATE_5MB: return 5500000;
3103 case IPW_TX_RATE_6MB: return 6000000;
3104 case IPW_TX_RATE_9MB: return 9000000;
3105 case IPW_TX_RATE_11MB: return 11000000;
3106 case IPW_TX_RATE_12MB: return 12000000;
3107 case IPW_TX_RATE_18MB: return 18000000;
3108 case IPW_TX_RATE_24MB: return 24000000;
3109 case IPW_TX_RATE_36MB: return 36000000;
3110 case IPW_TX_RATE_48MB: return 48000000;
3111 case IPW_TX_RATE_54MB: return 54000000;
3112 }
3113
3114 return 0;
3115}
3116
3117#define PERFECT_RSSI (-50)
3118#define WORST_RSSI (-85)
3119#define IPW_STATS_INTERVAL (2 * HZ)
3120static void ipw_gather_stats(struct ipw_priv *priv)
3121{
3122 u32 rx_err, rx_err_delta, rx_packets_delta;
3123 u32 tx_failures, tx_failures_delta, tx_packets_delta;
3124 u32 missed_beacons_percent, missed_beacons_delta;
3125 u32 quality = 0;
3126 u32 len = sizeof(u32);
3127 s16 rssi;
3128 u32 beacon_quality, signal_quality, tx_quality, rx_quality,
3129 rate_quality;
3130
3131 if (!(priv->status & STATUS_ASSOCIATED)) {
3132 priv->quality = 0;
3133 return;
3134 }
3135
3136 /* Update the statistics */
3137 ipw_get_ordinal(priv, IPW_ORD_STAT_MISSED_BEACONS,
3138 &priv->missed_beacons, &len);
3139 missed_beacons_delta = priv->missed_beacons -
3140 priv->last_missed_beacons;
3141 priv->last_missed_beacons = priv->missed_beacons;
3142 if (priv->assoc_request.beacon_interval) {
3143 missed_beacons_percent = missed_beacons_delta *
3144 (HZ * priv->assoc_request.beacon_interval) /
3145 (IPW_STATS_INTERVAL * 10);
3146 } else {
3147 missed_beacons_percent = 0;
3148 }
3149 average_add(&priv->average_missed_beacons, missed_beacons_percent);
3150
3151 ipw_get_ordinal(priv, IPW_ORD_STAT_RX_ERR_CRC, &rx_err, &len);
3152 rx_err_delta = rx_err - priv->last_rx_err;
3153 priv->last_rx_err = rx_err;
3154
3155 ipw_get_ordinal(priv, IPW_ORD_STAT_TX_FAILURE, &tx_failures, &len);
3156 tx_failures_delta = tx_failures - priv->last_tx_failures;
3157 priv->last_tx_failures = tx_failures;
3158
3159 rx_packets_delta = priv->rx_packets - priv->last_rx_packets;
3160 priv->last_rx_packets = priv->rx_packets;
3161
3162 tx_packets_delta = priv->tx_packets - priv->last_tx_packets;
3163 priv->last_tx_packets = priv->tx_packets;
3164
3165 /* Calculate quality based on the following:
3166 *
3167 * Missed beacon: 100% = 0, 0% = 70% missed
3168 * Rate: 60% = 1Mbs, 100% = Max
3169 * Rx and Tx errors represent a straight % of total Rx/Tx
3170 * RSSI: 100% = > -50, 0% = < -80
3171 * Rx errors: 100% = 0, 0% = 50% missed
3172 *
3173 * The lowest computed quality is used.
3174 *
3175 */
3176#define BEACON_THRESHOLD 5
3177 beacon_quality = 100 - missed_beacons_percent;
3178 if (beacon_quality < BEACON_THRESHOLD)
3179 beacon_quality = 0;
3180 else
3181 beacon_quality = (beacon_quality - BEACON_THRESHOLD) * 100 /
3182 (100 - BEACON_THRESHOLD);
3183 IPW_DEBUG_STATS("Missed beacon: %3d%% (%d%%)\n",
3184 beacon_quality, missed_beacons_percent);
3185
3186 priv->last_rate = ipw_get_current_rate(priv);
3187 rate_quality = priv->last_rate * 40 / priv->last_rate + 60;
3188 IPW_DEBUG_STATS("Rate quality : %3d%% (%dMbs)\n",
3189 rate_quality, priv->last_rate / 1000000);
3190
3191 if (rx_packets_delta > 100 &&
3192 rx_packets_delta + rx_err_delta)
3193 rx_quality = 100 - (rx_err_delta * 100) /
3194 (rx_packets_delta + rx_err_delta);
3195 else
3196 rx_quality = 100;
3197 IPW_DEBUG_STATS("Rx quality : %3d%% (%u errors, %u packets)\n",
3198 rx_quality, rx_err_delta, rx_packets_delta);
3199
3200 if (tx_packets_delta > 100 &&
3201 tx_packets_delta + tx_failures_delta)
3202 tx_quality = 100 - (tx_failures_delta * 100) /
3203 (tx_packets_delta + tx_failures_delta);
3204 else
3205 tx_quality = 100;
3206 IPW_DEBUG_STATS("Tx quality : %3d%% (%u errors, %u packets)\n",
3207 tx_quality, tx_failures_delta, tx_packets_delta);
3208
3209 rssi = average_value(&priv->average_rssi);
3210 if (rssi > PERFECT_RSSI)
3211 signal_quality = 100;
3212 else if (rssi < WORST_RSSI)
3213 signal_quality = 0;
3214 else
3215 signal_quality = (rssi - WORST_RSSI) * 100 /
3216 (PERFECT_RSSI - WORST_RSSI);
3217 IPW_DEBUG_STATS("Signal level : %3d%% (%d dBm)\n",
3218 signal_quality, rssi);
3219
3220 quality = min(beacon_quality,
3221 min(rate_quality,
3222 min(tx_quality, min(rx_quality, signal_quality))));
3223 if (quality == beacon_quality)
3224 IPW_DEBUG_STATS(
3225 "Quality (%d%%): Clamped to missed beacons.\n",
3226 quality);
3227 if (quality == rate_quality)
3228 IPW_DEBUG_STATS(
3229 "Quality (%d%%): Clamped to rate quality.\n",
3230 quality);
3231 if (quality == tx_quality)
3232 IPW_DEBUG_STATS(
3233 "Quality (%d%%): Clamped to Tx quality.\n",
3234 quality);
3235 if (quality == rx_quality)
3236 IPW_DEBUG_STATS(
3237 "Quality (%d%%): Clamped to Rx quality.\n",
3238 quality);
3239 if (quality == signal_quality)
3240 IPW_DEBUG_STATS(
3241 "Quality (%d%%): Clamped to signal quality.\n",
3242 quality);
3243
3244 priv->quality = quality;
3245
3246 queue_delayed_work(priv->workqueue, &priv->gather_stats,
3247 IPW_STATS_INTERVAL);
3248}
3249
3250/**
3251 * Handle host notification packet.
3252 * Called from interrupt routine
3253 */
3254static inline void ipw_rx_notification(struct ipw_priv* priv,
3255 struct ipw_rx_notification *notif)
3256{
3257 IPW_DEBUG_NOTIF("type = %i (%d bytes)\n",
3258 notif->subtype, notif->size);
3259
3260 switch (notif->subtype) {
3261 case HOST_NOTIFICATION_STATUS_ASSOCIATED: {
3262 struct notif_association *assoc = &notif->u.assoc;
3263
3264 switch (assoc->state) {
3265 case CMAS_ASSOCIATED: {
3266 IPW_DEBUG(IPW_DL_NOTIF | IPW_DL_STATE | IPW_DL_ASSOC,
3267 "associated: '%s' " MAC_FMT " \n",
3268 escape_essid(priv->essid, priv->essid_len),
3269 MAC_ARG(priv->bssid));
3270
3271 switch (priv->ieee->iw_mode) {
3272 case IW_MODE_INFRA:
3273 memcpy(priv->ieee->bssid, priv->bssid,
3274 ETH_ALEN);
3275 break;
3276
3277 case IW_MODE_ADHOC:
3278 memcpy(priv->ieee->bssid, priv->bssid,
3279 ETH_ALEN);
3280
3281 /* clear out the station table */
3282 priv->num_stations = 0;
3283
3284 IPW_DEBUG_ASSOC("queueing adhoc check\n");
3285 queue_delayed_work(priv->workqueue,
3286 &priv->adhoc_check,
3287 priv->assoc_request.beacon_interval);
3288 break;
3289 }
3290
3291 priv->status &= ~STATUS_ASSOCIATING;
3292 priv->status |= STATUS_ASSOCIATED;
3293
3294 netif_carrier_on(priv->net_dev);
3295 if (netif_queue_stopped(priv->net_dev)) {
3296 IPW_DEBUG_NOTIF("waking queue\n");
3297 netif_wake_queue(priv->net_dev);
3298 } else {
3299 IPW_DEBUG_NOTIF("starting queue\n");
3300 netif_start_queue(priv->net_dev);
3301 }
3302
3303 ipw_reset_stats(priv);
3304 /* Ensure the rate is updated immediately */
3305 priv->last_rate = ipw_get_current_rate(priv);
3306 schedule_work(&priv->gather_stats);
3307 notify_wx_assoc_event(priv);
3308
3309/* queue_delayed_work(priv->workqueue,
3310 &priv->request_scan,
3311 SCAN_ASSOCIATED_INTERVAL);
3312*/
3313 break;
3314 }
3315
3316 case CMAS_AUTHENTICATED: {
3317 if (priv->status & (STATUS_ASSOCIATED | STATUS_AUTH)) {
3318#ifdef CONFIG_IPW_DEBUG
3319 struct notif_authenticate *auth = &notif->u.auth;
3320 IPW_DEBUG(IPW_DL_NOTIF | IPW_DL_STATE | IPW_DL_ASSOC,
3321 "deauthenticated: '%s' " MAC_FMT ": (0x%04X) - %s \n",
3322 escape_essid(priv->essid, priv->essid_len),
3323 MAC_ARG(priv->bssid),
3324 ntohs(auth->status),
3325 ipw_get_status_code(ntohs(auth->status)));
3326#endif
3327
3328 priv->status &= ~(STATUS_ASSOCIATING |
3329 STATUS_AUTH |
3330 STATUS_ASSOCIATED);
3331
3332 netif_carrier_off(priv->net_dev);
3333 netif_stop_queue(priv->net_dev);
3334 queue_work(priv->workqueue, &priv->request_scan);
3335 notify_wx_assoc_event(priv);
3336 break;
3337 }
3338
3339 IPW_DEBUG(IPW_DL_NOTIF | IPW_DL_STATE | IPW_DL_ASSOC,
3340 "authenticated: '%s' " MAC_FMT "\n",
3341 escape_essid(priv->essid, priv->essid_len),
3342 MAC_ARG(priv->bssid));
3343 break;
3344 }
3345
3346 case CMAS_INIT: {
3347 IPW_DEBUG(IPW_DL_NOTIF | IPW_DL_STATE | IPW_DL_ASSOC,
3348 "disassociated: '%s' " MAC_FMT " \n",
3349 escape_essid(priv->essid, priv->essid_len),
3350 MAC_ARG(priv->bssid));
3351
3352 priv->status &= ~(
3353 STATUS_DISASSOCIATING |
3354 STATUS_ASSOCIATING |
3355 STATUS_ASSOCIATED |
3356 STATUS_AUTH);
3357
3358 netif_stop_queue(priv->net_dev);
3359 if (!(priv->status & STATUS_ROAMING)) {
3360 netif_carrier_off(priv->net_dev);
3361 notify_wx_assoc_event(priv);
3362
3363 /* Cancel any queued work ... */
3364 cancel_delayed_work(&priv->request_scan);
3365 cancel_delayed_work(&priv->adhoc_check);
3366
3367 /* Queue up another scan... */
3368 queue_work(priv->workqueue,
3369 &priv->request_scan);
3370
3371 cancel_delayed_work(&priv->gather_stats);
3372 } else {
3373 priv->status |= STATUS_ROAMING;
3374 queue_work(priv->workqueue,
3375 &priv->request_scan);
3376 }
3377
3378 ipw_reset_stats(priv);
3379 break;
3380 }
3381
3382 default:
3383 IPW_ERROR("assoc: unknown (%d)\n",
3384 assoc->state);
3385 break;
3386 }
3387
3388 break;
3389 }
3390
3391 case HOST_NOTIFICATION_STATUS_AUTHENTICATE: {
3392 struct notif_authenticate *auth = &notif->u.auth;
3393 switch (auth->state) {
3394 case CMAS_AUTHENTICATED:
3395 IPW_DEBUG(IPW_DL_NOTIF | IPW_DL_STATE,
3396 "authenticated: '%s' " MAC_FMT " \n",
3397 escape_essid(priv->essid, priv->essid_len),
3398 MAC_ARG(priv->bssid));
3399 priv->status |= STATUS_AUTH;
3400 break;
3401
3402 case CMAS_INIT:
3403 if (priv->status & STATUS_AUTH) {
3404 IPW_DEBUG(IPW_DL_NOTIF | IPW_DL_STATE | IPW_DL_ASSOC,
3405 "authentication failed (0x%04X): %s\n",
3406 ntohs(auth->status),
3407 ipw_get_status_code(ntohs(auth->status)));
3408 }
3409 IPW_DEBUG(IPW_DL_NOTIF | IPW_DL_STATE | IPW_DL_ASSOC,
3410 "deauthenticated: '%s' " MAC_FMT "\n",
3411 escape_essid(priv->essid, priv->essid_len),
3412 MAC_ARG(priv->bssid));
3413
3414 priv->status &= ~(STATUS_ASSOCIATING |
3415 STATUS_AUTH |
3416 STATUS_ASSOCIATED);
3417
3418 netif_carrier_off(priv->net_dev);
3419 netif_stop_queue(priv->net_dev);
3420 queue_work(priv->workqueue, &priv->request_scan);
3421 notify_wx_assoc_event(priv);
3422 break;
3423
3424 case CMAS_TX_AUTH_SEQ_1:
3425 IPW_DEBUG(IPW_DL_NOTIF | IPW_DL_STATE | IPW_DL_ASSOC,
3426 "AUTH_SEQ_1\n");
3427 break;
3428 case CMAS_RX_AUTH_SEQ_2:
3429 IPW_DEBUG(IPW_DL_NOTIF | IPW_DL_STATE | IPW_DL_ASSOC,
3430 "AUTH_SEQ_2\n");
3431 break;
3432 case CMAS_AUTH_SEQ_1_PASS:
3433 IPW_DEBUG(IPW_DL_NOTIF | IPW_DL_STATE | IPW_DL_ASSOC,
3434 "AUTH_SEQ_1_PASS\n");
3435 break;
3436 case CMAS_AUTH_SEQ_1_FAIL:
3437 IPW_DEBUG(IPW_DL_NOTIF | IPW_DL_STATE | IPW_DL_ASSOC,
3438 "AUTH_SEQ_1_FAIL\n");
3439 break;
3440 case CMAS_TX_AUTH_SEQ_3:
3441 IPW_DEBUG(IPW_DL_NOTIF | IPW_DL_STATE | IPW_DL_ASSOC,
3442 "AUTH_SEQ_3\n");
3443 break;
3444 case CMAS_RX_AUTH_SEQ_4:
3445 IPW_DEBUG(IPW_DL_NOTIF | IPW_DL_STATE | IPW_DL_ASSOC,
3446 "RX_AUTH_SEQ_4\n");
3447 break;
3448 case CMAS_AUTH_SEQ_2_PASS:
3449 IPW_DEBUG(IPW_DL_NOTIF | IPW_DL_STATE | IPW_DL_ASSOC,
3450 "AUTH_SEQ_2_PASS\n");
3451 break;
3452 case CMAS_AUTH_SEQ_2_FAIL:
3453 IPW_DEBUG(IPW_DL_NOTIF | IPW_DL_STATE | IPW_DL_ASSOC,
3454 "AUT_SEQ_2_FAIL\n");
3455 break;
3456 case CMAS_TX_ASSOC:
3457 IPW_DEBUG(IPW_DL_NOTIF | IPW_DL_STATE | IPW_DL_ASSOC,
3458 "TX_ASSOC\n");
3459 break;
3460 case CMAS_RX_ASSOC_RESP:
3461 IPW_DEBUG(IPW_DL_NOTIF | IPW_DL_STATE | IPW_DL_ASSOC,
3462 "RX_ASSOC_RESP\n");
3463 break;
3464 case CMAS_ASSOCIATED:
3465 IPW_DEBUG(IPW_DL_NOTIF | IPW_DL_STATE | IPW_DL_ASSOC,
3466 "ASSOCIATED\n");
3467 break;
3468 default:
3469 IPW_DEBUG_NOTIF("auth: failure - %d\n", auth->state);
3470 break;
3471 }
3472 break;
3473 }
3474
3475 case HOST_NOTIFICATION_STATUS_SCAN_CHANNEL_RESULT: {
3476 struct notif_channel_result *x = &notif->u.channel_result;
3477
3478 if (notif->size == sizeof(*x)) {
3479 IPW_DEBUG_SCAN("Scan result for channel %d\n",
3480 x->channel_num);
3481 } else {
3482 IPW_DEBUG_SCAN("Scan result of wrong size %d "
3483 "(should be %zd)\n",
3484 notif->size, sizeof(*x));
3485 }
3486 break;
3487 }
3488
3489 case HOST_NOTIFICATION_STATUS_SCAN_COMPLETED: {
3490 struct notif_scan_complete* x = &notif->u.scan_complete;
3491 if (notif->size == sizeof(*x)) {
3492 IPW_DEBUG_SCAN("Scan completed: type %d, %d channels, "
3493 "%d status\n",
3494 x->scan_type,
3495 x->num_channels,
3496 x->status);
3497 } else {
3498 IPW_ERROR("Scan completed of wrong size %d "
3499 "(should be %zd)\n",
3500 notif->size, sizeof(*x));
3501 }
3502
3503 priv->status &= ~(STATUS_SCANNING | STATUS_SCAN_ABORTING);
3504
3505 cancel_delayed_work(&priv->scan_check);
3506
3507 if (!(priv->status & (STATUS_ASSOCIATED |
3508 STATUS_ASSOCIATING |
3509 STATUS_ROAMING |
3510 STATUS_DISASSOCIATING)))
3511 queue_work(priv->workqueue, &priv->associate);
3512 else if (priv->status & STATUS_ROAMING) {
3513 /* If a scan completed and we are in roam mode, then
3514 * the scan that completed was the one requested as a
3515 * result of entering roam... so, schedule the
3516 * roam work */
3517 queue_work(priv->workqueue, &priv->roam);
3518 } else if (priv->status & STATUS_SCAN_PENDING)
3519 queue_work(priv->workqueue, &priv->request_scan);
3520
3521 priv->ieee->scans++;
3522 break;
3523 }
3524
3525 case HOST_NOTIFICATION_STATUS_FRAG_LENGTH: {
3526 struct notif_frag_length *x = &notif->u.frag_len;
3527
3528 if (notif->size == sizeof(*x)) {
3529 IPW_ERROR("Frag length: %d\n", x->frag_length);
3530 } else {
3531 IPW_ERROR("Frag length of wrong size %d "
3532 "(should be %zd)\n",
3533 notif->size, sizeof(*x));
3534 }
3535 break;
3536 }
3537
3538 case HOST_NOTIFICATION_STATUS_LINK_DETERIORATION: {
3539 struct notif_link_deterioration *x =
3540 &notif->u.link_deterioration;
3541 if (notif->size==sizeof(*x)) {
3542 IPW_DEBUG(IPW_DL_NOTIF | IPW_DL_STATE,
3543 "link deterioration: '%s' " MAC_FMT " \n",
3544 escape_essid(priv->essid, priv->essid_len),
3545 MAC_ARG(priv->bssid));
3546 memcpy(&priv->last_link_deterioration, x, sizeof(*x));
3547 } else {
3548 IPW_ERROR("Link Deterioration of wrong size %d "
3549 "(should be %zd)\n",
3550 notif->size, sizeof(*x));
3551 }
3552 break;
3553 }
3554
3555 case HOST_NOTIFICATION_DINO_CONFIG_RESPONSE: {
3556 IPW_ERROR("Dino config\n");
3557 if (priv->hcmd && priv->hcmd->cmd == HOST_CMD_DINO_CONFIG) {
3558 /* TODO: Do anything special? */
3559 } else {
3560 IPW_ERROR("Unexpected DINO_CONFIG_RESPONSE\n");
3561 }
3562 break;
3563 }
3564
3565 case HOST_NOTIFICATION_STATUS_BEACON_STATE: {
3566 struct notif_beacon_state *x = &notif->u.beacon_state;
3567 if (notif->size != sizeof(*x)) {
3568 IPW_ERROR("Beacon state of wrong size %d (should "
3569 "be %zd)\n", notif->size, sizeof(*x));
3570 break;
3571 }
3572
3573 if (x->state == HOST_NOTIFICATION_STATUS_BEACON_MISSING) {
3574 if (priv->status & STATUS_SCANNING) {
3575 /* Stop scan to keep fw from getting
3576 * stuck... */
3577 queue_work(priv->workqueue,
3578 &priv->abort_scan);
3579 }
3580
3581 if (x->number > priv->missed_beacon_threshold &&
3582 priv->status & STATUS_ASSOCIATED) {
3583 IPW_DEBUG(IPW_DL_INFO | IPW_DL_NOTIF |
3584 IPW_DL_STATE,
3585 "Missed beacon: %d - disassociate\n",
3586 x->number);
3587 queue_work(priv->workqueue,
3588 &priv->disassociate);
3589 } else if (x->number > priv->roaming_threshold) {
3590 IPW_DEBUG(IPW_DL_NOTIF | IPW_DL_STATE,
3591 "Missed beacon: %d - initiate "
3592 "roaming\n",
3593 x->number);
3594 queue_work(priv->workqueue,
3595 &priv->roam);
3596 } else {
3597 IPW_DEBUG_NOTIF("Missed beacon: %d\n",
3598 x->number);
3599 }
3600
3601 priv->notif_missed_beacons = x->number;
3602
3603 }
3604
3605
3606 break;
3607 }
3608
3609 case HOST_NOTIFICATION_STATUS_TGI_TX_KEY: {
3610 struct notif_tgi_tx_key *x = &notif->u.tgi_tx_key;
3611 if (notif->size==sizeof(*x)) {
3612 IPW_ERROR("TGi Tx Key: state 0x%02x sec type "
3613 "0x%02x station %d\n",
3614 x->key_state,x->security_type,
3615 x->station_index);
3616 break;
3617 }
3618
3619 IPW_ERROR("TGi Tx Key of wrong size %d (should be %zd)\n",
3620 notif->size, sizeof(*x));
3621 break;
3622 }
3623
3624 case HOST_NOTIFICATION_CALIB_KEEP_RESULTS: {
3625 struct notif_calibration *x = &notif->u.calibration;
3626
3627 if (notif->size == sizeof(*x)) {
3628 memcpy(&priv->calib, x, sizeof(*x));
3629 IPW_DEBUG_INFO("TODO: Calibration\n");
3630 break;
3631 }
3632
3633 IPW_ERROR("Calibration of wrong size %d (should be %zd)\n",
3634 notif->size, sizeof(*x));
3635 break;
3636 }
3637
3638 case HOST_NOTIFICATION_NOISE_STATS: {
3639 if (notif->size == sizeof(u32)) {
3640 priv->last_noise = (u8)(notif->u.noise.value & 0xff);
3641 average_add(&priv->average_noise, priv->last_noise);
3642 break;
3643 }
3644
3645 IPW_ERROR("Noise stat is wrong size %d (should be %zd)\n",
3646 notif->size, sizeof(u32));
3647 break;
3648 }
3649
3650 default:
3651 IPW_ERROR("Unknown notification: "
3652 "subtype=%d,flags=0x%2x,size=%d\n",
3653 notif->subtype, notif->flags, notif->size);
3654 }
3655}
3656
3657/**
3658 * Destroys all DMA structures and initialise them again
3659 *
3660 * @param priv
3661 * @return error code
3662 */
3663static int ipw_queue_reset(struct ipw_priv *priv)
3664{
3665 int rc = 0;
3666 /** @todo customize queue sizes */
3667 int nTx = 64, nTxCmd = 8;
3668 ipw_tx_queue_free(priv);
3669 /* Tx CMD queue */
3670 rc = ipw_queue_tx_init(priv, &priv->txq_cmd, nTxCmd,
3671 CX2_TX_CMD_QUEUE_READ_INDEX,
3672 CX2_TX_CMD_QUEUE_WRITE_INDEX,
3673 CX2_TX_CMD_QUEUE_BD_BASE,
3674 CX2_TX_CMD_QUEUE_BD_SIZE);
3675 if (rc) {
3676 IPW_ERROR("Tx Cmd queue init failed\n");
3677 goto error;
3678 }
3679 /* Tx queue(s) */
3680 rc = ipw_queue_tx_init(priv, &priv->txq[0], nTx,
3681 CX2_TX_QUEUE_0_READ_INDEX,
3682 CX2_TX_QUEUE_0_WRITE_INDEX,
3683 CX2_TX_QUEUE_0_BD_BASE,
3684 CX2_TX_QUEUE_0_BD_SIZE);
3685 if (rc) {
3686 IPW_ERROR("Tx 0 queue init failed\n");
3687 goto error;
3688 }
3689 rc = ipw_queue_tx_init(priv, &priv->txq[1], nTx,
3690 CX2_TX_QUEUE_1_READ_INDEX,
3691 CX2_TX_QUEUE_1_WRITE_INDEX,
3692 CX2_TX_QUEUE_1_BD_BASE,
3693 CX2_TX_QUEUE_1_BD_SIZE);
3694 if (rc) {
3695 IPW_ERROR("Tx 1 queue init failed\n");
3696 goto error;
3697 }
3698 rc = ipw_queue_tx_init(priv, &priv->txq[2], nTx,
3699 CX2_TX_QUEUE_2_READ_INDEX,
3700 CX2_TX_QUEUE_2_WRITE_INDEX,
3701 CX2_TX_QUEUE_2_BD_BASE,
3702 CX2_TX_QUEUE_2_BD_SIZE);
3703 if (rc) {
3704 IPW_ERROR("Tx 2 queue init failed\n");
3705 goto error;
3706 }
3707 rc = ipw_queue_tx_init(priv, &priv->txq[3], nTx,
3708 CX2_TX_QUEUE_3_READ_INDEX,
3709 CX2_TX_QUEUE_3_WRITE_INDEX,
3710 CX2_TX_QUEUE_3_BD_BASE,
3711 CX2_TX_QUEUE_3_BD_SIZE);
3712 if (rc) {
3713 IPW_ERROR("Tx 3 queue init failed\n");
3714 goto error;
3715 }
3716 /* statistics */
3717 priv->rx_bufs_min = 0;
3718 priv->rx_pend_max = 0;
3719 return rc;
3720
3721 error:
3722 ipw_tx_queue_free(priv);
3723 return rc;
3724}
3725
3726/**
3727 * Reclaim Tx queue entries no more used by NIC.
3728 *
3729 * When FW adwances 'R' index, all entries between old and
3730 * new 'R' index need to be reclaimed. As result, some free space
3731 * forms. If there is enough free space (> low mark), wake Tx queue.
3732 *
3733 * @note Need to protect against garbage in 'R' index
3734 * @param priv
3735 * @param txq
3736 * @param qindex
3737 * @return Number of used entries remains in the queue
3738 */
3739static int ipw_queue_tx_reclaim(struct ipw_priv *priv,
3740 struct clx2_tx_queue *txq, int qindex)
3741{
3742 u32 hw_tail;
3743 int used;
3744 struct clx2_queue *q = &txq->q;
3745
3746 hw_tail = ipw_read32(priv, q->reg_r);
3747 if (hw_tail >= q->n_bd) {
3748 IPW_ERROR
3749 ("Read index for DMA queue (%d) is out of range [0-%d)\n",
3750 hw_tail, q->n_bd);
3751 goto done;
3752 }
3753 for (; q->last_used != hw_tail;
3754 q->last_used = ipw_queue_inc_wrap(q->last_used, q->n_bd)) {
3755 ipw_queue_tx_free_tfd(priv, txq);
3756 priv->tx_packets++;
3757 }
3758 done:
3759 if (ipw_queue_space(q) > q->low_mark && qindex >= 0) {
3760 __maybe_wake_tx(priv);
3761 }
3762 used = q->first_empty - q->last_used;
3763 if (used < 0)
3764 used += q->n_bd;
3765
3766 return used;
3767}
3768
3769static int ipw_queue_tx_hcmd(struct ipw_priv *priv, int hcmd, void *buf,
3770 int len, int sync)
3771{
3772 struct clx2_tx_queue *txq = &priv->txq_cmd;
3773 struct clx2_queue *q = &txq->q;
3774 struct tfd_frame *tfd;
3775
3776 if (ipw_queue_space(q) < (sync ? 1 : 2)) {
3777 IPW_ERROR("No space for Tx\n");
3778 return -EBUSY;
3779 }
3780
3781 tfd = &txq->bd[q->first_empty];
3782 txq->txb[q->first_empty] = NULL;
3783
3784 memset(tfd, 0, sizeof(*tfd));
3785 tfd->control_flags.message_type = TX_HOST_COMMAND_TYPE;
3786 tfd->control_flags.control_bits = TFD_NEED_IRQ_MASK;
3787 priv->hcmd_seq++;
3788 tfd->u.cmd.index = hcmd;
3789 tfd->u.cmd.length = len;
3790 memcpy(tfd->u.cmd.payload, buf, len);
3791 q->first_empty = ipw_queue_inc_wrap(q->first_empty, q->n_bd);
3792 ipw_write32(priv, q->reg_w, q->first_empty);
3793 _ipw_read32(priv, 0x90);
3794
3795 return 0;
3796}
3797
3798
3799
3800/*
3801 * Rx theory of operation
3802 *
3803 * The host allocates 32 DMA target addresses and passes the host address
3804 * to the firmware at register CX2_RFDS_TABLE_LOWER + N * RFD_SIZE where N is
3805 * 0 to 31
3806 *
3807 * Rx Queue Indexes
3808 * The host/firmware share two index registers for managing the Rx buffers.
3809 *
3810 * The READ index maps to the first position that the firmware may be writing
3811 * to -- the driver can read up to (but not including) this position and get
3812 * good data.
3813 * The READ index is managed by the firmware once the card is enabled.
3814 *
3815 * The WRITE index maps to the last position the driver has read from -- the
3816 * position preceding WRITE is the last slot the firmware can place a packet.
3817 *
3818 * The queue is empty (no good data) if WRITE = READ - 1, and is full if
3819 * WRITE = READ.
3820 *
3821 * During initialization the host sets up the READ queue position to the first
3822 * INDEX position, and WRITE to the last (READ - 1 wrapped)
3823 *
3824 * When the firmware places a packet in a buffer it will advance the READ index
3825 * and fire the RX interrupt. The driver can then query the READ index and
3826 * process as many packets as possible, moving the WRITE index forward as it
3827 * resets the Rx queue buffers with new memory.
3828 *
3829 * The management in the driver is as follows:
3830 * + A list of pre-allocated SKBs is stored in ipw->rxq->rx_free. When
3831 * ipw->rxq->free_count drops to or below RX_LOW_WATERMARK, work is scheduled
3832 * to replensish the ipw->rxq->rx_free.
3833 * + In ipw_rx_queue_replenish (scheduled) if 'processed' != 'read' then the
3834 * ipw->rxq is replenished and the READ INDEX is updated (updating the
3835 * 'processed' and 'read' driver indexes as well)
3836 * + A received packet is processed and handed to the kernel network stack,
3837 * detached from the ipw->rxq. The driver 'processed' index is updated.
3838 * + The Host/Firmware ipw->rxq is replenished at tasklet time from the rx_free
3839 * list. If there are no allocated buffers in ipw->rxq->rx_free, the READ
3840 * INDEX is not incremented and ipw->status(RX_STALLED) is set. If there
3841 * were enough free buffers and RX_STALLED is set it is cleared.
3842 *
3843 *
3844 * Driver sequence:
3845 *
3846 * ipw_rx_queue_alloc() Allocates rx_free
3847 * ipw_rx_queue_replenish() Replenishes rx_free list from rx_used, and calls
3848 * ipw_rx_queue_restock
3849 * ipw_rx_queue_restock() Moves available buffers from rx_free into Rx
3850 * queue, updates firmware pointers, and updates
3851 * the WRITE index. If insufficient rx_free buffers
3852 * are available, schedules ipw_rx_queue_replenish
3853 *
3854 * -- enable interrupts --
3855 * ISR - ipw_rx() Detach ipw_rx_mem_buffers from pool up to the
3856 * READ INDEX, detaching the SKB from the pool.
3857 * Moves the packet buffer from queue to rx_used.
3858 * Calls ipw_rx_queue_restock to refill any empty
3859 * slots.
3860 * ...
3861 *
3862 */
3863
3864/*
3865 * If there are slots in the RX queue that need to be restocked,
3866 * and we have free pre-allocated buffers, fill the ranks as much
3867 * as we can pulling from rx_free.
3868 *
3869 * This moves the 'write' index forward to catch up with 'processed', and
3870 * also updates the memory address in the firmware to reference the new
3871 * target buffer.
3872 */
3873static void ipw_rx_queue_restock(struct ipw_priv *priv)
3874{
3875 struct ipw_rx_queue *rxq = priv->rxq;
3876 struct list_head *element;
3877 struct ipw_rx_mem_buffer *rxb;
3878 unsigned long flags;
3879 int write;
3880
3881 spin_lock_irqsave(&rxq->lock, flags);
3882 write = rxq->write;
3883 while ((rxq->write != rxq->processed) && (rxq->free_count)) {
3884 element = rxq->rx_free.next;
3885 rxb = list_entry(element, struct ipw_rx_mem_buffer, list);
3886 list_del(element);
3887
3888 ipw_write32(priv, CX2_RFDS_TABLE_LOWER + rxq->write * RFD_SIZE,
3889 rxb->dma_addr);
3890 rxq->queue[rxq->write] = rxb;
3891 rxq->write = (rxq->write + 1) % RX_QUEUE_SIZE;
3892 rxq->free_count--;
3893 }
3894 spin_unlock_irqrestore(&rxq->lock, flags);
3895
3896 /* If the pre-allocated buffer pool is dropping low, schedule to
3897 * refill it */
3898 if (rxq->free_count <= RX_LOW_WATERMARK)
3899 queue_work(priv->workqueue, &priv->rx_replenish);
3900
3901 /* If we've added more space for the firmware to place data, tell it */
3902 if (write != rxq->write)
3903 ipw_write32(priv, CX2_RX_WRITE_INDEX, rxq->write);
3904}
3905
3906/*
3907 * Move all used packet from rx_used to rx_free, allocating a new SKB for each.
3908 * Also restock the Rx queue via ipw_rx_queue_restock.
3909 *
3910 * This is called as a scheduled work item (except for during intialization)
3911 */
3912static void ipw_rx_queue_replenish(void *data)
3913{
3914 struct ipw_priv *priv = data;
3915 struct ipw_rx_queue *rxq = priv->rxq;
3916 struct list_head *element;
3917 struct ipw_rx_mem_buffer *rxb;
3918 unsigned long flags;
3919
3920 spin_lock_irqsave(&rxq->lock, flags);
3921 while (!list_empty(&rxq->rx_used)) {
3922 element = rxq->rx_used.next;
3923 rxb = list_entry(element, struct ipw_rx_mem_buffer, list);
3924 rxb->skb = alloc_skb(CX2_RX_BUF_SIZE, GFP_ATOMIC);
3925 if (!rxb->skb) {
3926 printk(KERN_CRIT "%s: Can not allocate SKB buffers.\n",
3927 priv->net_dev->name);
3928 /* We don't reschedule replenish work here -- we will
3929 * call the restock method and if it still needs
3930 * more buffers it will schedule replenish */
3931 break;
3932 }
3933 list_del(element);
3934
3935 rxb->rxb = (struct ipw_rx_buffer *)rxb->skb->data;
3936 rxb->dma_addr = pci_map_single(
3937 priv->pci_dev, rxb->skb->data, CX2_RX_BUF_SIZE,
3938 PCI_DMA_FROMDEVICE);
3939
3940 list_add_tail(&rxb->list, &rxq->rx_free);
3941 rxq->free_count++;
3942 }
3943 spin_unlock_irqrestore(&rxq->lock, flags);
3944
3945 ipw_rx_queue_restock(priv);
3946}
3947
3948/* Assumes that the skb field of the buffers in 'pool' is kept accurate.
3949 * If an SKB has been detached, the POOL needs to have it's SKB set to NULL
3950 * This free routine walks the list of POOL entries and if SKB is set to
3951 * non NULL it is unmapped and freed
3952 */
3953static void ipw_rx_queue_free(struct ipw_priv *priv,
3954 struct ipw_rx_queue *rxq)
3955{
3956 int i;
3957
3958 if (!rxq)
3959 return;
3960
3961 for (i = 0; i < RX_QUEUE_SIZE + RX_FREE_BUFFERS; i++) {
3962 if (rxq->pool[i].skb != NULL) {
3963 pci_unmap_single(priv->pci_dev, rxq->pool[i].dma_addr,
3964 CX2_RX_BUF_SIZE,
3965 PCI_DMA_FROMDEVICE);
3966 dev_kfree_skb(rxq->pool[i].skb);
3967 }
3968 }
3969
3970 kfree(rxq);
3971}
3972
3973static struct ipw_rx_queue *ipw_rx_queue_alloc(struct ipw_priv *priv)
3974{
3975 struct ipw_rx_queue *rxq;
3976 int i;
3977
3978 rxq = (struct ipw_rx_queue *)kmalloc(sizeof(*rxq), GFP_KERNEL);
3979 memset(rxq, 0, sizeof(*rxq));
3980 spin_lock_init(&rxq->lock);
3981 INIT_LIST_HEAD(&rxq->rx_free);
3982 INIT_LIST_HEAD(&rxq->rx_used);
3983
3984 /* Fill the rx_used queue with _all_ of the Rx buffers */
3985 for (i = 0; i < RX_FREE_BUFFERS + RX_QUEUE_SIZE; i++)
3986 list_add_tail(&rxq->pool[i].list, &rxq->rx_used);
3987
3988 /* Set us so that we have processed and used all buffers, but have
3989 * not restocked the Rx queue with fresh buffers */
3990 rxq->read = rxq->write = 0;
3991 rxq->processed = RX_QUEUE_SIZE - 1;
3992 rxq->free_count = 0;
3993
3994 return rxq;
3995}
3996
3997static int ipw_is_rate_in_mask(struct ipw_priv *priv, int ieee_mode, u8 rate)
3998{
3999 rate &= ~IEEE80211_BASIC_RATE_MASK;
4000 if (ieee_mode == IEEE_A) {
4001 switch (rate) {
4002 case IEEE80211_OFDM_RATE_6MB:
4003 return priv->rates_mask & IEEE80211_OFDM_RATE_6MB_MASK ?
4004 1 : 0;
4005 case IEEE80211_OFDM_RATE_9MB:
4006 return priv->rates_mask & IEEE80211_OFDM_RATE_9MB_MASK ?
4007 1 : 0;
4008 case IEEE80211_OFDM_RATE_12MB:
4009 return priv->rates_mask & IEEE80211_OFDM_RATE_12MB_MASK ?
4010 1 : 0;
4011 case IEEE80211_OFDM_RATE_18MB:
4012 return priv->rates_mask & IEEE80211_OFDM_RATE_18MB_MASK ?
4013 1 : 0;
4014 case IEEE80211_OFDM_RATE_24MB:
4015 return priv->rates_mask & IEEE80211_OFDM_RATE_24MB_MASK ?
4016 1 : 0;
4017 case IEEE80211_OFDM_RATE_36MB:
4018 return priv->rates_mask & IEEE80211_OFDM_RATE_36MB_MASK ?
4019 1 : 0;
4020 case IEEE80211_OFDM_RATE_48MB:
4021 return priv->rates_mask & IEEE80211_OFDM_RATE_48MB_MASK ?
4022 1 : 0;
4023 case IEEE80211_OFDM_RATE_54MB:
4024 return priv->rates_mask & IEEE80211_OFDM_RATE_54MB_MASK ?
4025 1 : 0;
4026 default:
4027 return 0;
4028 }
4029 }
4030
4031 /* B and G mixed */
4032 switch (rate) {
4033 case IEEE80211_CCK_RATE_1MB:
4034 return priv->rates_mask & IEEE80211_CCK_RATE_1MB_MASK ? 1 : 0;
4035 case IEEE80211_CCK_RATE_2MB:
4036 return priv->rates_mask & IEEE80211_CCK_RATE_2MB_MASK ? 1 : 0;
4037 case IEEE80211_CCK_RATE_5MB:
4038 return priv->rates_mask & IEEE80211_CCK_RATE_5MB_MASK ? 1 : 0;
4039 case IEEE80211_CCK_RATE_11MB:
4040 return priv->rates_mask & IEEE80211_CCK_RATE_11MB_MASK ? 1 : 0;
4041 }
4042
4043 /* If we are limited to B modulations, bail at this point */
4044 if (ieee_mode == IEEE_B)
4045 return 0;
4046
4047 /* G */
4048 switch (rate) {
4049 case IEEE80211_OFDM_RATE_6MB:
4050 return priv->rates_mask & IEEE80211_OFDM_RATE_6MB_MASK ? 1 : 0;
4051 case IEEE80211_OFDM_RATE_9MB:
4052 return priv->rates_mask & IEEE80211_OFDM_RATE_9MB_MASK ? 1 : 0;
4053 case IEEE80211_OFDM_RATE_12MB:
4054 return priv->rates_mask & IEEE80211_OFDM_RATE_12MB_MASK ? 1 : 0;
4055 case IEEE80211_OFDM_RATE_18MB:
4056 return priv->rates_mask & IEEE80211_OFDM_RATE_18MB_MASK ? 1 : 0;
4057 case IEEE80211_OFDM_RATE_24MB:
4058 return priv->rates_mask & IEEE80211_OFDM_RATE_24MB_MASK ? 1 : 0;
4059 case IEEE80211_OFDM_RATE_36MB:
4060 return priv->rates_mask & IEEE80211_OFDM_RATE_36MB_MASK ? 1 : 0;
4061 case IEEE80211_OFDM_RATE_48MB:
4062 return priv->rates_mask & IEEE80211_OFDM_RATE_48MB_MASK ? 1 : 0;
4063 case IEEE80211_OFDM_RATE_54MB:
4064 return priv->rates_mask & IEEE80211_OFDM_RATE_54MB_MASK ? 1 : 0;
4065 }
4066
4067 return 0;
4068}
4069
4070static int ipw_compatible_rates(struct ipw_priv *priv,
4071 const struct ieee80211_network *network,
4072 struct ipw_supported_rates *rates)
4073{
4074 int num_rates, i;
4075
4076 memset(rates, 0, sizeof(*rates));
4077 num_rates = min(network->rates_len, (u8)IPW_MAX_RATES);
4078 rates->num_rates = 0;
4079 for (i = 0; i < num_rates; i++) {
4080 if (!ipw_is_rate_in_mask(priv, network->mode, network->rates[i])) {
4081 IPW_DEBUG_SCAN("Rate %02X masked : 0x%08X\n",
4082 network->rates[i], priv->rates_mask);
4083 continue;
4084 }
4085
4086 rates->supported_rates[rates->num_rates++] = network->rates[i];
4087 }
4088
4089 num_rates = min(network->rates_ex_len, (u8)(IPW_MAX_RATES - num_rates));
4090 for (i = 0; i < num_rates; i++) {
4091 if (!ipw_is_rate_in_mask(priv, network->mode, network->rates_ex[i])) {
4092 IPW_DEBUG_SCAN("Rate %02X masked : 0x%08X\n",
4093 network->rates_ex[i], priv->rates_mask);
4094 continue;
4095 }
4096
4097 rates->supported_rates[rates->num_rates++] = network->rates_ex[i];
4098 }
4099
4100 return rates->num_rates;
4101}
4102
4103static inline void ipw_copy_rates(struct ipw_supported_rates *dest,
4104 const struct ipw_supported_rates *src)
4105{
4106 u8 i;
4107 for (i = 0; i < src->num_rates; i++)
4108 dest->supported_rates[i] = src->supported_rates[i];
4109 dest->num_rates = src->num_rates;
4110}
4111
4112/* TODO: Look at sniffed packets in the air to determine if the basic rate
4113 * mask should ever be used -- right now all callers to add the scan rates are
4114 * set with the modulation = CCK, so BASIC_RATE_MASK is never set... */
4115static void ipw_add_cck_scan_rates(struct ipw_supported_rates *rates,
4116 u8 modulation, u32 rate_mask)
4117{
4118 u8 basic_mask = (IEEE80211_OFDM_MODULATION == modulation) ?
4119 IEEE80211_BASIC_RATE_MASK : 0;
4120
4121 if (rate_mask & IEEE80211_CCK_RATE_1MB_MASK)
4122 rates->supported_rates[rates->num_rates++] =
4123 IEEE80211_BASIC_RATE_MASK | IEEE80211_CCK_RATE_1MB;
4124
4125 if (rate_mask & IEEE80211_CCK_RATE_2MB_MASK)
4126 rates->supported_rates[rates->num_rates++] =
4127 IEEE80211_BASIC_RATE_MASK | IEEE80211_CCK_RATE_2MB;
4128
4129 if (rate_mask & IEEE80211_CCK_RATE_5MB_MASK)
4130 rates->supported_rates[rates->num_rates++] = basic_mask |
4131 IEEE80211_CCK_RATE_5MB;
4132
4133 if (rate_mask & IEEE80211_CCK_RATE_11MB_MASK)
4134 rates->supported_rates[rates->num_rates++] = basic_mask |
4135 IEEE80211_CCK_RATE_11MB;
4136}
4137
4138static void ipw_add_ofdm_scan_rates(struct ipw_supported_rates *rates,
4139 u8 modulation, u32 rate_mask)
4140{
4141 u8 basic_mask = (IEEE80211_OFDM_MODULATION == modulation) ?
4142 IEEE80211_BASIC_RATE_MASK : 0;
4143
4144 if (rate_mask & IEEE80211_OFDM_RATE_6MB_MASK)
4145 rates->supported_rates[rates->num_rates++] = basic_mask |
4146 IEEE80211_OFDM_RATE_6MB;
4147
4148 if (rate_mask & IEEE80211_OFDM_RATE_9MB_MASK)
4149 rates->supported_rates[rates->num_rates++] =
4150 IEEE80211_OFDM_RATE_9MB;
4151
4152 if (rate_mask & IEEE80211_OFDM_RATE_12MB_MASK)
4153 rates->supported_rates[rates->num_rates++] = basic_mask |
4154 IEEE80211_OFDM_RATE_12MB;
4155
4156 if (rate_mask & IEEE80211_OFDM_RATE_18MB_MASK)
4157 rates->supported_rates[rates->num_rates++] =
4158 IEEE80211_OFDM_RATE_18MB;
4159
4160 if (rate_mask & IEEE80211_OFDM_RATE_24MB_MASK)
4161 rates->supported_rates[rates->num_rates++] = basic_mask |
4162 IEEE80211_OFDM_RATE_24MB;
4163
4164 if (rate_mask & IEEE80211_OFDM_RATE_36MB_MASK)
4165 rates->supported_rates[rates->num_rates++] =
4166 IEEE80211_OFDM_RATE_36MB;
4167
4168 if (rate_mask & IEEE80211_OFDM_RATE_48MB_MASK)
4169 rates->supported_rates[rates->num_rates++] =
4170 IEEE80211_OFDM_RATE_48MB;
4171
4172 if (rate_mask & IEEE80211_OFDM_RATE_54MB_MASK)
4173 rates->supported_rates[rates->num_rates++] =
4174 IEEE80211_OFDM_RATE_54MB;
4175}
4176
4177struct ipw_network_match {
4178 struct ieee80211_network *network;
4179 struct ipw_supported_rates rates;
4180};
4181
4182static int ipw_best_network(
4183 struct ipw_priv *priv,
4184 struct ipw_network_match *match,
4185 struct ieee80211_network *network,
4186 int roaming)
4187{
4188 struct ipw_supported_rates rates;
4189
4190 /* Verify that this network's capability is compatible with the
4191 * current mode (AdHoc or Infrastructure) */
4192 if ((priv->ieee->iw_mode == IW_MODE_INFRA &&
4193 !(network->capability & WLAN_CAPABILITY_ESS)) ||
4194 (priv->ieee->iw_mode == IW_MODE_ADHOC &&
4195 !(network->capability & WLAN_CAPABILITY_IBSS))) {
4196 IPW_DEBUG_ASSOC("Network '%s (" MAC_FMT ")' excluded due to "
4197 "capability mismatch.\n",
4198 escape_essid(network->ssid, network->ssid_len),
4199 MAC_ARG(network->bssid));
4200 return 0;
4201 }
4202
4203 /* If we do not have an ESSID for this AP, we can not associate with
4204 * it */
4205 if (network->flags & NETWORK_EMPTY_ESSID) {
4206 IPW_DEBUG_ASSOC("Network '%s (" MAC_FMT ")' excluded "
4207 "because of hidden ESSID.\n",
4208 escape_essid(network->ssid, network->ssid_len),
4209 MAC_ARG(network->bssid));
4210 return 0;
4211 }
4212
4213 if (unlikely(roaming)) {
4214 /* If we are roaming, then ensure check if this is a valid
4215 * network to try and roam to */
4216 if ((network->ssid_len != match->network->ssid_len) ||
4217 memcmp(network->ssid, match->network->ssid,
4218 network->ssid_len)) {
4219 IPW_DEBUG_ASSOC("Netowrk '%s (" MAC_FMT ")' excluded "
4220 "because of non-network ESSID.\n",
4221 escape_essid(network->ssid,
4222 network->ssid_len),
4223 MAC_ARG(network->bssid));
4224 return 0;
4225 }
4226 } else {
4227 /* If an ESSID has been configured then compare the broadcast
4228 * ESSID to ours */
4229 if ((priv->config & CFG_STATIC_ESSID) &&
4230 ((network->ssid_len != priv->essid_len) ||
4231 memcmp(network->ssid, priv->essid,
4232 min(network->ssid_len, priv->essid_len)))) {
4233 char escaped[IW_ESSID_MAX_SIZE * 2 + 1];
4234 strncpy(escaped, escape_essid(
4235 network->ssid, network->ssid_len),
4236 sizeof(escaped));
4237 IPW_DEBUG_ASSOC("Network '%s (" MAC_FMT ")' excluded "
4238 "because of ESSID mismatch: '%s'.\n",
4239 escaped, MAC_ARG(network->bssid),
4240 escape_essid(priv->essid, priv->essid_len));
4241 return 0;
4242 }
4243 }
4244
4245 /* If the old network rate is better than this one, don't bother
4246 * testing everything else. */
4247 if (match->network && match->network->stats.rssi >
4248 network->stats.rssi) {
4249 char escaped[IW_ESSID_MAX_SIZE * 2 + 1];
4250 strncpy(escaped,
4251 escape_essid(network->ssid, network->ssid_len),
4252 sizeof(escaped));
4253 IPW_DEBUG_ASSOC("Network '%s (" MAC_FMT ")' excluded because "
4254 "'%s (" MAC_FMT ")' has a stronger signal.\n",
4255 escaped, MAC_ARG(network->bssid),
4256 escape_essid(match->network->ssid,
4257 match->network->ssid_len),
4258 MAC_ARG(match->network->bssid));
4259 return 0;
4260 }
4261
4262 /* If this network has already had an association attempt within the
4263 * last 3 seconds, do not try and associate again... */
4264 if (network->last_associate &&
4265 time_after(network->last_associate + (HZ * 5UL), jiffies)) {
4266 IPW_DEBUG_ASSOC("Network '%s (" MAC_FMT ")' excluded "
4267 "because of storming (%lu since last "
4268 "assoc attempt).\n",
4269 escape_essid(network->ssid, network->ssid_len),
4270 MAC_ARG(network->bssid),
4271 (jiffies - network->last_associate) / HZ);
4272 return 0;
4273 }
4274
4275 /* Now go through and see if the requested network is valid... */
4276 if (priv->ieee->scan_age != 0 &&
4277 jiffies - network->last_scanned > priv->ieee->scan_age) {
4278 IPW_DEBUG_ASSOC("Network '%s (" MAC_FMT ")' excluded "
4279 "because of age: %lums.\n",
4280 escape_essid(network->ssid, network->ssid_len),
4281 MAC_ARG(network->bssid),
4282 (jiffies - network->last_scanned) / (HZ / 100));
4283 return 0;
4284 }
4285
4286 if ((priv->config & CFG_STATIC_CHANNEL) &&
4287 (network->channel != priv->channel)) {
4288 IPW_DEBUG_ASSOC("Network '%s (" MAC_FMT ")' excluded "
4289 "because of channel mismatch: %d != %d.\n",
4290 escape_essid(network->ssid, network->ssid_len),
4291 MAC_ARG(network->bssid),
4292 network->channel, priv->channel);
4293 return 0;
4294 }
4295
4296 /* Verify privacy compatability */
4297 if (((priv->capability & CAP_PRIVACY_ON) ? 1 : 0) !=
4298 ((network->capability & WLAN_CAPABILITY_PRIVACY) ? 1 : 0)) {
4299 IPW_DEBUG_ASSOC("Network '%s (" MAC_FMT ")' excluded "
4300 "because of privacy mismatch: %s != %s.\n",
4301 escape_essid(network->ssid, network->ssid_len),
4302 MAC_ARG(network->bssid),
4303 priv->capability & CAP_PRIVACY_ON ? "on" :
4304 "off",
4305 network->capability &
4306 WLAN_CAPABILITY_PRIVACY ?"on" : "off");
4307 return 0;
4308 }
4309
4310 if ((priv->config & CFG_STATIC_BSSID) &&
4311 memcmp(network->bssid, priv->bssid, ETH_ALEN)) {
4312 IPW_DEBUG_ASSOC("Network '%s (" MAC_FMT ")' excluded "
4313 "because of BSSID mismatch: " MAC_FMT ".\n",
4314 escape_essid(network->ssid, network->ssid_len),
4315 MAC_ARG(network->bssid),
4316 MAC_ARG(priv->bssid));
4317 return 0;
4318 }
4319
4320 /* Filter out any incompatible freq / mode combinations */
4321 if (!ieee80211_is_valid_mode(priv->ieee, network->mode)) {
4322 IPW_DEBUG_ASSOC("Network '%s (" MAC_FMT ")' excluded "
4323 "because of invalid frequency/mode "
4324 "combination.\n",
4325 escape_essid(network->ssid, network->ssid_len),
4326 MAC_ARG(network->bssid));
4327 return 0;
4328 }
4329
4330 ipw_compatible_rates(priv, network, &rates);
4331 if (rates.num_rates == 0) {
4332 IPW_DEBUG_ASSOC("Network '%s (" MAC_FMT ")' excluded "
4333 "because of no compatible rates.\n",
4334 escape_essid(network->ssid, network->ssid_len),
4335 MAC_ARG(network->bssid));
4336 return 0;
4337 }
4338
4339 /* TODO: Perform any further minimal comparititive tests. We do not
4340 * want to put too much policy logic here; intelligent scan selection
4341 * should occur within a generic IEEE 802.11 user space tool. */
4342
4343 /* Set up 'new' AP to this network */
4344 ipw_copy_rates(&match->rates, &rates);
4345 match->network = network;
4346
4347 IPW_DEBUG_ASSOC("Network '%s (" MAC_FMT ")' is a viable match.\n",
4348 escape_essid(network->ssid, network->ssid_len),
4349 MAC_ARG(network->bssid));
4350
4351 return 1;
4352}
4353
4354
4355static void ipw_adhoc_create(struct ipw_priv *priv,
4356 struct ieee80211_network *network)
4357{
4358 /*
4359 * For the purposes of scanning, we can set our wireless mode
4360 * to trigger scans across combinations of bands, but when it
4361 * comes to creating a new ad-hoc network, we have tell the FW
4362 * exactly which band to use.
4363 *
4364 * We also have the possibility of an invalid channel for the
4365 * chossen band. Attempting to create a new ad-hoc network
4366 * with an invalid channel for wireless mode will trigger a
4367 * FW fatal error.
4368 */
4369 network->mode = is_valid_channel(priv->ieee->mode, priv->channel);
4370 if (network->mode) {
4371 network->channel = priv->channel;
4372 } else {
4373 IPW_WARNING("Overriding invalid channel\n");
4374 if (priv->ieee->mode & IEEE_A) {
4375 network->mode = IEEE_A;
4376 priv->channel = band_a_active_channel[0];
4377 } else if (priv->ieee->mode & IEEE_G) {
4378 network->mode = IEEE_G;
4379 priv->channel = band_b_active_channel[0];
4380 } else {
4381 network->mode = IEEE_B;
4382 priv->channel = band_b_active_channel[0];
4383 }
4384 }
4385
4386 network->channel = priv->channel;
4387 priv->config |= CFG_ADHOC_PERSIST;
4388 ipw_create_bssid(priv, network->bssid);
4389 network->ssid_len = priv->essid_len;
4390 memcpy(network->ssid, priv->essid, priv->essid_len);
4391 memset(&network->stats, 0, sizeof(network->stats));
4392 network->capability = WLAN_CAPABILITY_IBSS;
4393 if (priv->capability & CAP_PRIVACY_ON)
4394 network->capability |= WLAN_CAPABILITY_PRIVACY;
4395 network->rates_len = min(priv->rates.num_rates, MAX_RATES_LENGTH);
4396 memcpy(network->rates, priv->rates.supported_rates,
4397 network->rates_len);
4398 network->rates_ex_len = priv->rates.num_rates - network->rates_len;
4399 memcpy(network->rates_ex,
4400 &priv->rates.supported_rates[network->rates_len],
4401 network->rates_ex_len);
4402 network->last_scanned = 0;
4403 network->flags = 0;
4404 network->last_associate = 0;
4405 network->time_stamp[0] = 0;
4406 network->time_stamp[1] = 0;
4407 network->beacon_interval = 100; /* Default */
4408 network->listen_interval = 10; /* Default */
4409 network->atim_window = 0; /* Default */
4410#ifdef CONFIG_IEEE80211_WPA
4411 network->wpa_ie_len = 0;
4412 network->rsn_ie_len = 0;
4413#endif /* CONFIG_IEEE80211_WPA */
4414}
4415
4416static void ipw_send_wep_keys(struct ipw_priv *priv)
4417{
4418 struct ipw_wep_key *key;
4419 int i;
4420 struct host_cmd cmd = {
4421 .cmd = IPW_CMD_WEP_KEY,
4422 .len = sizeof(*key)
4423 };
4424
4425 key = (struct ipw_wep_key *)&cmd.param;
4426 key->cmd_id = DINO_CMD_WEP_KEY;
4427 key->seq_num = 0;
4428
4429 for (i = 0; i < 4; i++) {
4430 key->key_index = i;
4431 if (!(priv->sec.flags & (1 << i))) {
4432 key->key_size = 0;
4433 } else {
4434 key->key_size = priv->sec.key_sizes[i];
4435 memcpy(key->key, priv->sec.keys[i], key->key_size);
4436 }
4437
4438 if (ipw_send_cmd(priv, &cmd)) {
4439 IPW_ERROR("failed to send WEP_KEY command\n");
4440 return;
4441 }
4442 }
4443}
4444
4445static void ipw_adhoc_check(void *data)
4446{
4447 struct ipw_priv *priv = data;
4448
4449 if (priv->missed_adhoc_beacons++ > priv->missed_beacon_threshold &&
4450 !(priv->config & CFG_ADHOC_PERSIST)) {
4451 IPW_DEBUG_SCAN("Disassociating due to missed beacons\n");
4452 ipw_remove_current_network(priv);
4453 ipw_disassociate(priv);
4454 return;
4455 }
4456
4457 queue_delayed_work(priv->workqueue, &priv->adhoc_check,
4458 priv->assoc_request.beacon_interval);
4459}
4460
4461#ifdef CONFIG_IPW_DEBUG
4462static void ipw_debug_config(struct ipw_priv *priv)
4463{
4464 IPW_DEBUG_INFO("Scan completed, no valid APs matched "
4465 "[CFG 0x%08X]\n", priv->config);
4466 if (priv->config & CFG_STATIC_CHANNEL)
4467 IPW_DEBUG_INFO("Channel locked to %d\n",
4468 priv->channel);
4469 else
4470 IPW_DEBUG_INFO("Channel unlocked.\n");
4471 if (priv->config & CFG_STATIC_ESSID)
4472 IPW_DEBUG_INFO("ESSID locked to '%s'\n",
4473 escape_essid(priv->essid,
4474 priv->essid_len));
4475 else
4476 IPW_DEBUG_INFO("ESSID unlocked.\n");
4477 if (priv->config & CFG_STATIC_BSSID)
4478 IPW_DEBUG_INFO("BSSID locked to %d\n", priv->channel);
4479 else
4480 IPW_DEBUG_INFO("BSSID unlocked.\n");
4481 if (priv->capability & CAP_PRIVACY_ON)
4482 IPW_DEBUG_INFO("PRIVACY on\n");
4483 else
4484 IPW_DEBUG_INFO("PRIVACY off\n");
4485 IPW_DEBUG_INFO("RATE MASK: 0x%08X\n", priv->rates_mask);
4486}
4487#else
4488#define ipw_debug_config(x) do {} while (0)
4489#endif
4490
4491static inline void ipw_set_fixed_rate(struct ipw_priv *priv,
4492 struct ieee80211_network *network)
4493{
4494 /* TODO: Verify that this works... */
4495 struct ipw_fixed_rate fr = {
4496 .tx_rates = priv->rates_mask
4497 };
4498 u32 reg;
4499 u16 mask = 0;
4500
4501 /* Identify 'current FW band' and match it with the fixed
4502 * Tx rates */
4503
4504 switch (priv->ieee->freq_band) {
4505 case IEEE80211_52GHZ_BAND: /* A only */
4506 /* IEEE_A */
4507 if (priv->rates_mask & ~IEEE80211_OFDM_RATES_MASK) {
4508 /* Invalid fixed rate mask */
4509 fr.tx_rates = 0;
4510 break;
4511 }
4512
4513 fr.tx_rates >>= IEEE80211_OFDM_SHIFT_MASK_A;
4514 break;
4515
4516 default: /* 2.4Ghz or Mixed */
4517 /* IEEE_B */
4518 if (network->mode == IEEE_B) {
4519 if (fr.tx_rates & ~IEEE80211_CCK_RATES_MASK) {
4520 /* Invalid fixed rate mask */
4521 fr.tx_rates = 0;
4522 }
4523 break;
4524 }
4525
4526 /* IEEE_G */
4527 if (fr.tx_rates & ~(IEEE80211_CCK_RATES_MASK |
4528 IEEE80211_OFDM_RATES_MASK)) {
4529 /* Invalid fixed rate mask */
4530 fr.tx_rates = 0;
4531 break;
4532 }
4533
4534 if (IEEE80211_OFDM_RATE_6MB_MASK & fr.tx_rates) {
4535 mask |= (IEEE80211_OFDM_RATE_6MB_MASK >> 1);
4536 fr.tx_rates &= ~IEEE80211_OFDM_RATE_6MB_MASK;
4537 }
4538
4539 if (IEEE80211_OFDM_RATE_9MB_MASK & fr.tx_rates) {
4540 mask |= (IEEE80211_OFDM_RATE_9MB_MASK >> 1);
4541 fr.tx_rates &= ~IEEE80211_OFDM_RATE_9MB_MASK;
4542 }
4543
4544 if (IEEE80211_OFDM_RATE_12MB_MASK & fr.tx_rates) {
4545 mask |= (IEEE80211_OFDM_RATE_12MB_MASK >> 1);
4546 fr.tx_rates &= ~IEEE80211_OFDM_RATE_12MB_MASK;
4547 }
4548
4549 fr.tx_rates |= mask;
4550 break;
4551 }
4552
4553 reg = ipw_read32(priv, IPW_MEM_FIXED_OVERRIDE);
4554 ipw_write_reg32(priv, reg, *(u32*)&fr);
4555}
4556
4557static int ipw_associate_network(struct ipw_priv *priv,
4558 struct ieee80211_network *network,
4559 struct ipw_supported_rates *rates,
4560 int roaming)
4561{
4562 int err;
4563
4564 if (priv->config & CFG_FIXED_RATE)
4565 ipw_set_fixed_rate(priv, network);
4566
4567 if (!(priv->config & CFG_STATIC_ESSID)) {
4568 priv->essid_len = min(network->ssid_len,
4569 (u8)IW_ESSID_MAX_SIZE);
4570 memcpy(priv->essid, network->ssid, priv->essid_len);
4571 }
4572
4573 network->last_associate = jiffies;
4574
4575 memset(&priv->assoc_request, 0, sizeof(priv->assoc_request));
4576 priv->assoc_request.channel = network->channel;
4577 if ((priv->capability & CAP_PRIVACY_ON) &&
4578 (priv->capability & CAP_SHARED_KEY)) {
4579 priv->assoc_request.auth_type = AUTH_SHARED_KEY;
4580 priv->assoc_request.auth_key = priv->sec.active_key;
4581 } else {
4582 priv->assoc_request.auth_type = AUTH_OPEN;
4583 priv->assoc_request.auth_key = 0;
4584 }
4585
4586 if (priv->capability & CAP_PRIVACY_ON)
4587 ipw_send_wep_keys(priv);
4588
4589 /*
4590 * It is valid for our ieee device to support multiple modes, but
4591 * when it comes to associating to a given network we have to choose
4592 * just one mode.
4593 */
4594 if (network->mode & priv->ieee->mode & IEEE_A)
4595 priv->assoc_request.ieee_mode = IPW_A_MODE;
4596 else if (network->mode & priv->ieee->mode & IEEE_G)
4597 priv->assoc_request.ieee_mode = IPW_G_MODE;
4598 else if (network->mode & priv->ieee->mode & IEEE_B)
4599 priv->assoc_request.ieee_mode = IPW_B_MODE;
4600
4601 IPW_DEBUG_ASSOC("%sssocation attempt: '%s', channel %d, "
4602 "802.11%c [%d], enc=%s%s%s%c%c\n",
4603 roaming ? "Rea" : "A",
4604 escape_essid(priv->essid, priv->essid_len),
4605 network->channel,
4606 ipw_modes[priv->assoc_request.ieee_mode],
4607 rates->num_rates,
4608 priv->capability & CAP_PRIVACY_ON ? "on " : "off",
4609 priv->capability & CAP_PRIVACY_ON ?
4610 (priv->capability & CAP_SHARED_KEY ? "(shared)" :
4611 "(open)") : "",
4612 priv->capability & CAP_PRIVACY_ON ? " key=" : "",
4613 priv->capability & CAP_PRIVACY_ON ?
4614 '1' + priv->sec.active_key : '.',
4615 priv->capability & CAP_PRIVACY_ON ?
4616 '.' : ' ');
4617
4618 priv->assoc_request.beacon_interval = network->beacon_interval;
4619 if ((priv->ieee->iw_mode == IW_MODE_ADHOC) &&
4620 (network->time_stamp[0] == 0) &&
4621 (network->time_stamp[1] == 0)) {
4622 priv->assoc_request.assoc_type = HC_IBSS_START;
4623 priv->assoc_request.assoc_tsf_msw = 0;
4624 priv->assoc_request.assoc_tsf_lsw = 0;
4625 } else {
4626 if (unlikely(roaming))
4627 priv->assoc_request.assoc_type = HC_REASSOCIATE;
4628 else
4629 priv->assoc_request.assoc_type = HC_ASSOCIATE;
4630 priv->assoc_request.assoc_tsf_msw = network->time_stamp[1];
4631 priv->assoc_request.assoc_tsf_lsw = network->time_stamp[0];
4632 }
4633
4634 memcpy(&priv->assoc_request.bssid, network->bssid, ETH_ALEN);
4635
4636 if (priv->ieee->iw_mode == IW_MODE_ADHOC) {
4637 memset(&priv->assoc_request.dest, 0xFF, ETH_ALEN);
4638 priv->assoc_request.atim_window = network->atim_window;
4639 } else {
4640 memcpy(&priv->assoc_request.dest, network->bssid,
4641 ETH_ALEN);
4642 priv->assoc_request.atim_window = 0;
4643 }
4644
4645 priv->assoc_request.capability = network->capability;
4646 priv->assoc_request.listen_interval = network->listen_interval;
4647
4648 err = ipw_send_ssid(priv, priv->essid, priv->essid_len);
4649 if (err) {
4650 IPW_DEBUG_HC("Attempt to send SSID command failed.\n");
4651 return err;
4652 }
4653
4654 rates->ieee_mode = priv->assoc_request.ieee_mode;
4655 rates->purpose = IPW_RATE_CONNECT;
4656 ipw_send_supported_rates(priv, rates);
4657
4658 if (priv->assoc_request.ieee_mode == IPW_G_MODE)
4659 priv->sys_config.dot11g_auto_detection = 1;
4660 else
4661 priv->sys_config.dot11g_auto_detection = 0;
4662 err = ipw_send_system_config(priv, &priv->sys_config);
4663 if (err) {
4664 IPW_DEBUG_HC("Attempt to send sys config command failed.\n");
4665 return err;
4666 }
4667
4668 IPW_DEBUG_ASSOC("Association sensitivity: %d\n", network->stats.rssi);
4669 err = ipw_set_sensitivity(priv, network->stats.rssi);
4670 if (err) {
4671 IPW_DEBUG_HC("Attempt to send associate command failed.\n");
4672 return err;
4673 }
4674
4675 /*
4676 * If preemption is enabled, it is possible for the association
4677 * to complete before we return from ipw_send_associate. Therefore
4678 * we have to be sure and update our priviate data first.
4679 */
4680 priv->channel = network->channel;
4681 memcpy(priv->bssid, network->bssid, ETH_ALEN);
4682 priv->status |= STATUS_ASSOCIATING;
4683 priv->status &= ~STATUS_SECURITY_UPDATED;
4684
4685 priv->assoc_network = network;
4686
4687 err = ipw_send_associate(priv, &priv->assoc_request);
4688 if (err) {
4689 IPW_DEBUG_HC("Attempt to send associate command failed.\n");
4690 return err;
4691 }
4692
4693 IPW_DEBUG(IPW_DL_STATE, "associating: '%s' " MAC_FMT " \n",
4694 escape_essid(priv->essid, priv->essid_len),
4695 MAC_ARG(priv->bssid));
4696
4697 return 0;
4698}
4699
4700static void ipw_roam(void *data)
4701{
4702 struct ipw_priv *priv = data;
4703 struct ieee80211_network *network = NULL;
4704 struct ipw_network_match match = {
4705 .network = priv->assoc_network
4706 };
4707
4708 /* The roaming process is as follows:
4709 *
4710 * 1. Missed beacon threshold triggers the roaming process by
4711 * setting the status ROAM bit and requesting a scan.
4712 * 2. When the scan completes, it schedules the ROAM work
4713 * 3. The ROAM work looks at all of the known networks for one that
4714 * is a better network than the currently associated. If none
4715 * found, the ROAM process is over (ROAM bit cleared)
4716 * 4. If a better network is found, a disassociation request is
4717 * sent.
4718 * 5. When the disassociation completes, the roam work is again
4719 * scheduled. The second time through, the driver is no longer
4720 * associated, and the newly selected network is sent an
4721 * association request.
4722 * 6. At this point ,the roaming process is complete and the ROAM
4723 * status bit is cleared.
4724 */
4725
4726 /* If we are no longer associated, and the roaming bit is no longer
4727 * set, then we are not actively roaming, so just return */
4728 if (!(priv->status & (STATUS_ASSOCIATED | STATUS_ROAMING)))
4729 return;
4730
4731 if (priv->status & STATUS_ASSOCIATED) {
4732 /* First pass through ROAM process -- look for a better
4733 * network */
4734 u8 rssi = priv->assoc_network->stats.rssi;
4735 priv->assoc_network->stats.rssi = -128;
4736 list_for_each_entry(network, &priv->ieee->network_list, list) {
4737 if (network != priv->assoc_network)
4738 ipw_best_network(priv, &match, network, 1);
4739 }
4740 priv->assoc_network->stats.rssi = rssi;
4741
4742 if (match.network == priv->assoc_network) {
4743 IPW_DEBUG_ASSOC("No better APs in this network to "
4744 "roam to.\n");
4745 priv->status &= ~STATUS_ROAMING;
4746 ipw_debug_config(priv);
4747 return;
4748 }
4749
4750 ipw_send_disassociate(priv, 1);
4751 priv->assoc_network = match.network;
4752
4753 return;
4754 }
4755
4756 /* Second pass through ROAM process -- request association */
4757 ipw_compatible_rates(priv, priv->assoc_network, &match.rates);
4758 ipw_associate_network(priv, priv->assoc_network, &match.rates, 1);
4759 priv->status &= ~STATUS_ROAMING;
4760}
4761
4762static void ipw_associate(void *data)
4763{
4764 struct ipw_priv *priv = data;
4765
4766 struct ieee80211_network *network = NULL;
4767 struct ipw_network_match match = {
4768 .network = NULL
4769 };
4770 struct ipw_supported_rates *rates;
4771 struct list_head *element;
4772
4773 if (!(priv->config & CFG_ASSOCIATE) &&
4774 !(priv->config & (CFG_STATIC_ESSID |
4775 CFG_STATIC_CHANNEL |
4776 CFG_STATIC_BSSID))) {
4777 IPW_DEBUG_ASSOC("Not attempting association (associate=0)\n");
4778 return;
4779 }
4780
4781 list_for_each_entry(network, &priv->ieee->network_list, list)
4782 ipw_best_network(priv, &match, network, 0);
4783
4784 network = match.network;
4785 rates = &match.rates;
4786
4787 if (network == NULL &&
4788 priv->ieee->iw_mode == IW_MODE_ADHOC &&
4789 priv->config & CFG_ADHOC_CREATE &&
4790 priv->config & CFG_STATIC_ESSID &&
4791 !list_empty(&priv->ieee->network_free_list)) {
4792 element = priv->ieee->network_free_list.next;
4793 network = list_entry(element, struct ieee80211_network,
4794 list);
4795 ipw_adhoc_create(priv, network);
4796 rates = &priv->rates;
4797 list_del(element);
4798 list_add_tail(&network->list, &priv->ieee->network_list);
4799 }
4800
4801 /* If we reached the end of the list, then we don't have any valid
4802 * matching APs */
4803 if (!network) {
4804 ipw_debug_config(priv);
4805
4806 queue_delayed_work(priv->workqueue, &priv->request_scan,
4807 SCAN_INTERVAL);
4808
4809 return;
4810 }
4811
4812 ipw_associate_network(priv, network, rates, 0);
4813}
4814
4815static inline void ipw_handle_data_packet(struct ipw_priv *priv,
4816 struct ipw_rx_mem_buffer *rxb,
4817 struct ieee80211_rx_stats *stats)
4818{
4819 struct ipw_rx_packet *pkt = (struct ipw_rx_packet *)rxb->skb->data;
4820
4821 /* We received data from the HW, so stop the watchdog */
4822 priv->net_dev->trans_start = jiffies;
4823
4824 /* We only process data packets if the
4825 * interface is open */
4826 if (unlikely((pkt->u.frame.length + IPW_RX_FRAME_SIZE) >
4827 skb_tailroom(rxb->skb))) {
4828 priv->ieee->stats.rx_errors++;
4829 priv->wstats.discard.misc++;
4830 IPW_DEBUG_DROP("Corruption detected! Oh no!\n");
4831 return;
4832 } else if (unlikely(!netif_running(priv->net_dev))) {
4833 priv->ieee->stats.rx_dropped++;
4834 priv->wstats.discard.misc++;
4835 IPW_DEBUG_DROP("Dropping packet while interface is not up.\n");
4836 return;
4837 }
4838
4839 /* Advance skb->data to the start of the actual payload */
4840 skb_reserve(rxb->skb, offsetof(struct ipw_rx_packet, u.frame.data));
4841
4842 /* Set the size of the skb to the size of the frame */
4843 skb_put(rxb->skb, pkt->u.frame.length);
4844
4845 IPW_DEBUG_RX("Rx packet of %d bytes.\n", rxb->skb->len);
4846
4847 if (!ieee80211_rx(priv->ieee, rxb->skb, stats))
4848 priv->ieee->stats.rx_errors++;
4849 else /* ieee80211_rx succeeded, so it now owns the SKB */
4850 rxb->skb = NULL;
4851}
4852
4853
4854/*
4855 * Main entry function for recieving a packet with 80211 headers. This
4856 * should be called when ever the FW has notified us that there is a new
4857 * skb in the recieve queue.
4858 */
4859static void ipw_rx(struct ipw_priv *priv)
4860{
4861 struct ipw_rx_mem_buffer *rxb;
4862 struct ipw_rx_packet *pkt;
4863 struct ieee80211_hdr *header;
4864 u32 r, w, i;
4865 u8 network_packet;
4866
4867 r = ipw_read32(priv, CX2_RX_READ_INDEX);
4868 w = ipw_read32(priv, CX2_RX_WRITE_INDEX);
4869 i = (priv->rxq->processed + 1) % RX_QUEUE_SIZE;
4870
4871 while (i != r) {
4872 rxb = priv->rxq->queue[i];
4873#ifdef CONFIG_IPW_DEBUG
4874 if (unlikely(rxb == NULL)) {
4875 printk(KERN_CRIT "Queue not allocated!\n");
4876 break;
4877 }
4878#endif
4879 priv->rxq->queue[i] = NULL;
4880
4881 pci_dma_sync_single_for_cpu(priv->pci_dev, rxb->dma_addr,
4882 CX2_RX_BUF_SIZE,
4883 PCI_DMA_FROMDEVICE);
4884
4885 pkt = (struct ipw_rx_packet *)rxb->skb->data;
4886 IPW_DEBUG_RX("Packet: type=%02X seq=%02X bits=%02X\n",
4887 pkt->header.message_type,
4888 pkt->header.rx_seq_num,
4889 pkt->header.control_bits);
4890
4891 switch (pkt->header.message_type) {
4892 case RX_FRAME_TYPE: /* 802.11 frame */ {
4893 struct ieee80211_rx_stats stats = {
4894 .rssi = pkt->u.frame.rssi_dbm -
4895 IPW_RSSI_TO_DBM,
4896 .signal = pkt->u.frame.signal,
4897 .rate = pkt->u.frame.rate,
4898 .mac_time = jiffies,
4899 .received_channel =
4900 pkt->u.frame.received_channel,
4901 .freq = (pkt->u.frame.control & (1<<0)) ?
4902 IEEE80211_24GHZ_BAND : IEEE80211_52GHZ_BAND,
4903 .len = pkt->u.frame.length,
4904 };
4905
4906 if (stats.rssi != 0)
4907 stats.mask |= IEEE80211_STATMASK_RSSI;
4908 if (stats.signal != 0)
4909 stats.mask |= IEEE80211_STATMASK_SIGNAL;
4910 if (stats.rate != 0)
4911 stats.mask |= IEEE80211_STATMASK_RATE;
4912
4913 priv->rx_packets++;
4914
4915#ifdef CONFIG_IPW_PROMISC
4916 if (priv->ieee->iw_mode == IW_MODE_MONITOR) {
4917 ipw_handle_data_packet(priv, rxb, &stats);
4918 break;
4919 }
4920#endif
4921
4922 header = (struct ieee80211_hdr *)(rxb->skb->data +
4923 IPW_RX_FRAME_SIZE);
4924 /* TODO: Check Ad-Hoc dest/source and make sure
4925 * that we are actually parsing these packets
4926 * correctly -- we should probably use the
4927 * frame control of the packet and disregard
4928 * the current iw_mode */
4929 switch (priv->ieee->iw_mode) {
4930 case IW_MODE_ADHOC:
4931 network_packet =
4932 !memcmp(header->addr1,
4933 priv->net_dev->dev_addr,
4934 ETH_ALEN) ||
4935 !memcmp(header->addr3,
4936 priv->bssid, ETH_ALEN) ||
4937 is_broadcast_ether_addr(header->addr1) ||
4938 is_multicast_ether_addr(header->addr1);
4939 break;
4940
4941 case IW_MODE_INFRA:
4942 default:
4943 network_packet =
4944 !memcmp(header->addr3,
4945 priv->bssid, ETH_ALEN) ||
4946 !memcmp(header->addr1,
4947 priv->net_dev->dev_addr,
4948 ETH_ALEN) ||
4949 is_broadcast_ether_addr(header->addr1) ||
4950 is_multicast_ether_addr(header->addr1);
4951 break;
4952 }
4953
4954 if (network_packet && priv->assoc_network) {
4955 priv->assoc_network->stats.rssi = stats.rssi;
4956 average_add(&priv->average_rssi,
4957 stats.rssi);
4958 priv->last_rx_rssi = stats.rssi;
4959 }
4960
4961 IPW_DEBUG_RX("Frame: len=%u\n", pkt->u.frame.length);
4962
4963 if (pkt->u.frame.length < frame_hdr_len(header)) {
4964 IPW_DEBUG_DROP("Received packet is too small. "
4965 "Dropping.\n");
4966 priv->ieee->stats.rx_errors++;
4967 priv->wstats.discard.misc++;
4968 break;
4969 }
4970
4971 switch (WLAN_FC_GET_TYPE(header->frame_ctl)) {
4972 case IEEE80211_FTYPE_MGMT:
4973 ieee80211_rx_mgt(priv->ieee, header, &stats);
4974 if (priv->ieee->iw_mode == IW_MODE_ADHOC &&
4975 ((WLAN_FC_GET_STYPE(header->frame_ctl) ==
4976 IEEE80211_STYPE_PROBE_RESP) ||
4977 (WLAN_FC_GET_STYPE(header->frame_ctl) ==
4978 IEEE80211_STYPE_BEACON)) &&
4979 !memcmp(header->addr3, priv->bssid, ETH_ALEN))
4980 ipw_add_station(priv, header->addr2);
4981 break;
4982
4983 case IEEE80211_FTYPE_CTL:
4984 break;
4985
4986 case IEEE80211_FTYPE_DATA:
4987 if (network_packet)
4988 ipw_handle_data_packet(priv, rxb, &stats);
4989 else
4990 IPW_DEBUG_DROP("Dropping: " MAC_FMT
4991 ", " MAC_FMT ", " MAC_FMT "\n",
4992 MAC_ARG(header->addr1), MAC_ARG(header->addr2),
4993 MAC_ARG(header->addr3));
4994 break;
4995 }
4996 break;
4997 }
4998
4999 case RX_HOST_NOTIFICATION_TYPE: {
5000 IPW_DEBUG_RX("Notification: subtype=%02X flags=%02X size=%d\n",
5001 pkt->u.notification.subtype,
5002 pkt->u.notification.flags,
5003 pkt->u.notification.size);
5004 ipw_rx_notification(priv, &pkt->u.notification);
5005 break;
5006 }
5007
5008 default:
5009 IPW_DEBUG_RX("Bad Rx packet of type %d\n",
5010 pkt->header.message_type);
5011 break;
5012 }
5013
5014 /* For now we just don't re-use anything. We can tweak this
5015 * later to try and re-use notification packets and SKBs that
5016 * fail to Rx correctly */
5017 if (rxb->skb != NULL) {
5018 dev_kfree_skb_any(rxb->skb);
5019 rxb->skb = NULL;
5020 }
5021
5022 pci_unmap_single(priv->pci_dev, rxb->dma_addr,
5023 CX2_RX_BUF_SIZE, PCI_DMA_FROMDEVICE);
5024 list_add_tail(&rxb->list, &priv->rxq->rx_used);
5025
5026 i = (i + 1) % RX_QUEUE_SIZE;
5027 }
5028
5029 /* Backtrack one entry */
5030 priv->rxq->processed = (i ? i : RX_QUEUE_SIZE) - 1;
5031
5032 ipw_rx_queue_restock(priv);
5033}
5034
5035static void ipw_abort_scan(struct ipw_priv *priv)
5036{
5037 int err;
5038
5039 if (priv->status & STATUS_SCAN_ABORTING) {
5040 IPW_DEBUG_HC("Ignoring concurrent scan abort request.\n");
5041 return;
5042 }
5043 priv->status |= STATUS_SCAN_ABORTING;
5044
5045 err = ipw_send_scan_abort(priv);
5046 if (err)
5047 IPW_DEBUG_HC("Request to abort scan failed.\n");
5048}
5049
5050static int ipw_request_scan(struct ipw_priv *priv)
5051{
5052 struct ipw_scan_request_ext scan;
5053 int channel_index = 0;
5054 int i, err, scan_type;
5055
5056 if (priv->status & STATUS_EXIT_PENDING) {
5057 IPW_DEBUG_SCAN("Aborting scan due to device shutdown\n");
5058 priv->status |= STATUS_SCAN_PENDING;
5059 return 0;
5060 }
5061
5062 if (priv->status & STATUS_SCANNING) {
5063 IPW_DEBUG_HC("Concurrent scan requested. Aborting first.\n");
5064 priv->status |= STATUS_SCAN_PENDING;
5065 ipw_abort_scan(priv);
5066 return 0;
5067 }
5068
5069 if (priv->status & STATUS_SCAN_ABORTING) {
5070 IPW_DEBUG_HC("Scan request while abort pending. Queuing.\n");
5071 priv->status |= STATUS_SCAN_PENDING;
5072 return 0;
5073 }
5074
5075 if (priv->status & STATUS_RF_KILL_MASK) {
5076 IPW_DEBUG_HC("Aborting scan due to RF Kill activation\n");
5077 priv->status |= STATUS_SCAN_PENDING;
5078 return 0;
5079 }
5080
5081 memset(&scan, 0, sizeof(scan));
5082
5083 scan.dwell_time[IPW_SCAN_ACTIVE_BROADCAST_SCAN] = 20;
5084 scan.dwell_time[IPW_SCAN_ACTIVE_BROADCAST_AND_DIRECT_SCAN] = 20;
5085 scan.dwell_time[IPW_SCAN_PASSIVE_FULL_DWELL_SCAN] = 20;
5086
5087 scan.full_scan_index = ieee80211_get_scans(priv->ieee);
5088 /* If we are roaming, then make this a directed scan for the current
5089 * network. Otherwise, ensure that every other scan is a fast
5090 * channel hop scan */
5091 if ((priv->status & STATUS_ROAMING) || (
5092 !(priv->status & STATUS_ASSOCIATED) &&
5093 (priv->config & CFG_STATIC_ESSID) &&
5094 (scan.full_scan_index % 2))) {
5095 err = ipw_send_ssid(priv, priv->essid, priv->essid_len);
5096 if (err) {
5097 IPW_DEBUG_HC("Attempt to send SSID command failed.\n");
5098 return err;
5099 }
5100
5101 scan_type = IPW_SCAN_ACTIVE_BROADCAST_AND_DIRECT_SCAN;
5102 } else {
5103 scan_type = IPW_SCAN_ACTIVE_BROADCAST_SCAN;
5104 }
5105
5106 if (priv->ieee->freq_band & IEEE80211_52GHZ_BAND) {
5107 int start = channel_index;
5108 for (i = 0; i < MAX_A_CHANNELS; i++) {
5109 if (band_a_active_channel[i] == 0)
5110 break;
5111 if ((priv->status & STATUS_ASSOCIATED) &&
5112 band_a_active_channel[i] == priv->channel)
5113 continue;
5114 channel_index++;
5115 scan.channels_list[channel_index] =
5116 band_a_active_channel[i];
5117 ipw_set_scan_type(&scan, channel_index, scan_type);
5118 }
5119
5120 if (start != channel_index) {
5121 scan.channels_list[start] = (u8)(IPW_A_MODE << 6) |
5122 (channel_index - start);
5123 channel_index++;
5124 }
5125 }
5126
5127 if (priv->ieee->freq_band & IEEE80211_24GHZ_BAND) {
5128 int start = channel_index;
5129 for (i = 0; i < MAX_B_CHANNELS; i++) {
5130 if (band_b_active_channel[i] == 0)
5131 break;
5132 if ((priv->status & STATUS_ASSOCIATED) &&
5133 band_b_active_channel[i] == priv->channel)
5134 continue;
5135 channel_index++;
5136 scan.channels_list[channel_index] =
5137 band_b_active_channel[i];
5138 ipw_set_scan_type(&scan, channel_index, scan_type);
5139 }
5140
5141 if (start != channel_index) {
5142 scan.channels_list[start] = (u8)(IPW_B_MODE << 6) |
5143 (channel_index - start);
5144 }
5145 }
5146
5147 err = ipw_send_scan_request_ext(priv, &scan);
5148 if (err) {
5149 IPW_DEBUG_HC("Sending scan command failed: %08X\n",
5150 err);
5151 return -EIO;
5152 }
5153
5154 priv->status |= STATUS_SCANNING;
5155 priv->status &= ~STATUS_SCAN_PENDING;
5156
5157 return 0;
5158}
5159
5160/*
5161 * This file defines the Wireless Extension handlers. It does not
5162 * define any methods of hardware manipulation and relies on the
5163 * functions defined in ipw_main to provide the HW interaction.
5164 *
5165 * The exception to this is the use of the ipw_get_ordinal()
5166 * function used to poll the hardware vs. making unecessary calls.
5167 *
5168 */
5169
5170static int ipw_wx_get_name(struct net_device *dev,
5171 struct iw_request_info *info,
5172 union iwreq_data *wrqu, char *extra)
5173{
5174 struct ipw_priv *priv = ieee80211_priv(dev);
5175 if (!(priv->status & STATUS_ASSOCIATED))
5176 strcpy(wrqu->name, "unassociated");
5177 else
5178 snprintf(wrqu->name, IFNAMSIZ, "IEEE 802.11%c",
5179 ipw_modes[priv->assoc_request.ieee_mode]);
5180 IPW_DEBUG_WX("Name: %s\n", wrqu->name);
5181 return 0;
5182}
5183
5184static int ipw_set_channel(struct ipw_priv *priv, u8 channel)
5185{
5186 if (channel == 0) {
5187 IPW_DEBUG_INFO("Setting channel to ANY (0)\n");
5188 priv->config &= ~CFG_STATIC_CHANNEL;
5189 if (!(priv->status & (STATUS_SCANNING | STATUS_ASSOCIATED |
5190 STATUS_ASSOCIATING))) {
5191 IPW_DEBUG_ASSOC("Attempting to associate with new "
5192 "parameters.\n");
5193 ipw_associate(priv);
5194 }
5195
5196 return 0;
5197 }
5198
5199 priv->config |= CFG_STATIC_CHANNEL;
5200
5201 if (priv->channel == channel) {
5202 IPW_DEBUG_INFO(
5203 "Request to set channel to current value (%d)\n",
5204 channel);
5205 return 0;
5206 }
5207
5208 IPW_DEBUG_INFO("Setting channel to %i\n", (int)channel);
5209 priv->channel = channel;
5210
5211 /* If we are currently associated, or trying to associate
5212 * then see if this is a new channel (causing us to disassociate) */
5213 if (priv->status & (STATUS_ASSOCIATED | STATUS_ASSOCIATING)) {
5214 IPW_DEBUG_ASSOC("Disassociating due to channel change.\n");
5215 ipw_disassociate(priv);
5216 } else {
5217 ipw_associate(priv);
5218 }
5219
5220 return 0;
5221}
5222
5223static int ipw_wx_set_freq(struct net_device *dev,
5224 struct iw_request_info *info,
5225 union iwreq_data *wrqu, char *extra)
5226{
5227 struct ipw_priv *priv = ieee80211_priv(dev);
5228 struct iw_freq *fwrq = &wrqu->freq;
5229
5230 /* if setting by freq convert to channel */
5231 if (fwrq->e == 1) {
5232 if ((fwrq->m >= (int) 2.412e8 &&
5233 fwrq->m <= (int) 2.487e8)) {
5234 int f = fwrq->m / 100000;
5235 int c = 0;
5236
5237 while ((c < REG_MAX_CHANNEL) &&
5238 (f != ipw_frequencies[c]))
5239 c++;
5240
5241 /* hack to fall through */
5242 fwrq->e = 0;
5243 fwrq->m = c + 1;
5244 }
5245 }
5246
5247 if (fwrq->e > 0 || fwrq->m > 1000)
5248 return -EOPNOTSUPP;
5249
5250 IPW_DEBUG_WX("SET Freq/Channel -> %d \n", fwrq->m);
5251 return ipw_set_channel(priv, (u8)fwrq->m);
5252
5253 return 0;
5254}
5255
5256
5257static int ipw_wx_get_freq(struct net_device *dev,
5258 struct iw_request_info *info,
5259 union iwreq_data *wrqu, char *extra)
5260{
5261 struct ipw_priv *priv = ieee80211_priv(dev);
5262
5263 wrqu->freq.e = 0;
5264
5265 /* If we are associated, trying to associate, or have a statically
5266 * configured CHANNEL then return that; otherwise return ANY */
5267 if (priv->config & CFG_STATIC_CHANNEL ||
5268 priv->status & (STATUS_ASSOCIATING | STATUS_ASSOCIATED))
5269 wrqu->freq.m = priv->channel;
5270 else
5271 wrqu->freq.m = 0;
5272
5273 IPW_DEBUG_WX("GET Freq/Channel -> %d \n", priv->channel);
5274 return 0;
5275}
5276
5277static int ipw_wx_set_mode(struct net_device *dev,
5278 struct iw_request_info *info,
5279 union iwreq_data *wrqu, char *extra)
5280{
5281 struct ipw_priv *priv = ieee80211_priv(dev);
5282 int err = 0;
5283
5284 IPW_DEBUG_WX("Set MODE: %d\n", wrqu->mode);
5285
5286 if (wrqu->mode == priv->ieee->iw_mode)
5287 return 0;
5288
5289 switch (wrqu->mode) {
5290#ifdef CONFIG_IPW_PROMISC
5291 case IW_MODE_MONITOR:
5292#endif
5293 case IW_MODE_ADHOC:
5294 case IW_MODE_INFRA:
5295 break;
5296 case IW_MODE_AUTO:
5297 wrqu->mode = IW_MODE_INFRA;
5298 break;
5299 default:
5300 return -EINVAL;
5301 }
5302
5303#ifdef CONFIG_IPW_PROMISC
5304 if (priv->ieee->iw_mode == IW_MODE_MONITOR)
5305 priv->net_dev->type = ARPHRD_ETHER;
5306
5307 if (wrqu->mode == IW_MODE_MONITOR)
5308 priv->net_dev->type = ARPHRD_IEEE80211;
5309#endif /* CONFIG_IPW_PROMISC */
5310
5311#ifdef CONFIG_PM
5312 /* Free the existing firmware and reset the fw_loaded
5313 * flag so ipw_load() will bring in the new firmawre */
5314 if (fw_loaded) {
5315 fw_loaded = 0;
5316 }
5317
5318 release_firmware(bootfw);
5319 release_firmware(ucode);
5320 release_firmware(firmware);
5321 bootfw = ucode = firmware = NULL;
5322#endif
5323
5324 priv->ieee->iw_mode = wrqu->mode;
5325 ipw_adapter_restart(priv);
5326
5327 return err;
5328}
5329
5330static int ipw_wx_get_mode(struct net_device *dev,
5331 struct iw_request_info *info,
5332 union iwreq_data *wrqu, char *extra)
5333{
5334 struct ipw_priv *priv = ieee80211_priv(dev);
5335
5336 wrqu->mode = priv->ieee->iw_mode;
5337 IPW_DEBUG_WX("Get MODE -> %d\n", wrqu->mode);
5338
5339 return 0;
5340}
5341
5342
5343#define DEFAULT_RTS_THRESHOLD 2304U
5344#define MIN_RTS_THRESHOLD 1U
5345#define MAX_RTS_THRESHOLD 2304U
5346#define DEFAULT_BEACON_INTERVAL 100U
5347#define DEFAULT_SHORT_RETRY_LIMIT 7U
5348#define DEFAULT_LONG_RETRY_LIMIT 4U
5349
5350/* Values are in microsecond */
5351static const s32 timeout_duration[] = {
5352 350000,
5353 250000,
5354 75000,
5355 37000,
5356 25000,
5357};
5358
5359static const s32 period_duration[] = {
5360 400000,
5361 700000,
5362 1000000,
5363 1000000,
5364 1000000
5365};
5366
5367static int ipw_wx_get_range(struct net_device *dev,
5368 struct iw_request_info *info,
5369 union iwreq_data *wrqu, char *extra)
5370{
5371 struct ipw_priv *priv = ieee80211_priv(dev);
5372 struct iw_range *range = (struct iw_range *)extra;
5373 u16 val;
5374 int i;
5375
5376 wrqu->data.length = sizeof(*range);
5377 memset(range, 0, sizeof(*range));
5378
5379 /* 54Mbs == ~27 Mb/s real (802.11g) */
5380 range->throughput = 27 * 1000 * 1000;
5381
5382 range->max_qual.qual = 100;
5383 /* TODO: Find real max RSSI and stick here */
5384 range->max_qual.level = 0;
5385 range->max_qual.noise = 0;
5386 range->max_qual.updated = 7; /* Updated all three */
5387
5388 range->avg_qual.qual = 70;
5389 /* TODO: Find real 'good' to 'bad' threshol value for RSSI */
5390 range->avg_qual.level = 0; /* FIXME to real average level */
5391 range->avg_qual.noise = 0;
5392 range->avg_qual.updated = 7; /* Updated all three */
5393
5394 range->num_bitrates = min(priv->rates.num_rates, (u8)IW_MAX_BITRATES);
5395
5396 for (i = 0; i < range->num_bitrates; i++)
5397 range->bitrate[i] = (priv->rates.supported_rates[i] & 0x7F) *
5398 500000;
5399
5400 range->max_rts = DEFAULT_RTS_THRESHOLD;
5401 range->min_frag = MIN_FRAG_THRESHOLD;
5402 range->max_frag = MAX_FRAG_THRESHOLD;
5403
5404 range->encoding_size[0] = 5;
5405 range->encoding_size[1] = 13;
5406 range->num_encoding_sizes = 2;
5407 range->max_encoding_tokens = WEP_KEYS;
5408
5409 /* Set the Wireless Extension versions */
5410 range->we_version_compiled = WIRELESS_EXT;
5411 range->we_version_source = 16;
5412
5413 range->num_channels = FREQ_COUNT;
5414
5415 val = 0;
5416 for (i = 0; i < FREQ_COUNT; i++) {
5417 range->freq[val].i = i + 1;
5418 range->freq[val].m = ipw_frequencies[i] * 100000;
5419 range->freq[val].e = 1;
5420 val++;
5421
5422 if (val == IW_MAX_FREQUENCIES)
5423 break;
5424 }
5425 range->num_frequency = val;
5426
5427 IPW_DEBUG_WX("GET Range\n");
5428 return 0;
5429}
5430
5431static int ipw_wx_set_wap(struct net_device *dev,
5432 struct iw_request_info *info,
5433 union iwreq_data *wrqu, char *extra)
5434{
5435 struct ipw_priv *priv = ieee80211_priv(dev);
5436
5437 static const unsigned char any[] = {
5438 0xff, 0xff, 0xff, 0xff, 0xff, 0xff
5439 };
5440 static const unsigned char off[] = {
5441 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
5442 };
5443
5444 if (wrqu->ap_addr.sa_family != ARPHRD_ETHER)
5445 return -EINVAL;
5446
5447 if (!memcmp(any, wrqu->ap_addr.sa_data, ETH_ALEN) ||
5448 !memcmp(off, wrqu->ap_addr.sa_data, ETH_ALEN)) {
5449 /* we disable mandatory BSSID association */
5450 IPW_DEBUG_WX("Setting AP BSSID to ANY\n");
5451 priv->config &= ~CFG_STATIC_BSSID;
5452 if (!(priv->status & (STATUS_SCANNING | STATUS_ASSOCIATED |
5453 STATUS_ASSOCIATING))) {
5454 IPW_DEBUG_ASSOC("Attempting to associate with new "
5455 "parameters.\n");
5456 ipw_associate(priv);
5457 }
5458
5459 return 0;
5460 }
5461
5462 priv->config |= CFG_STATIC_BSSID;
5463 if (!memcmp(priv->bssid, wrqu->ap_addr.sa_data, ETH_ALEN)) {
5464 IPW_DEBUG_WX("BSSID set to current BSSID.\n");
5465 return 0;
5466 }
5467
5468 IPW_DEBUG_WX("Setting mandatory BSSID to " MAC_FMT "\n",
5469 MAC_ARG(wrqu->ap_addr.sa_data));
5470
5471 memcpy(priv->bssid, wrqu->ap_addr.sa_data, ETH_ALEN);
5472
5473 /* If we are currently associated, or trying to associate
5474 * then see if this is a new BSSID (causing us to disassociate) */
5475 if (priv->status & (STATUS_ASSOCIATED | STATUS_ASSOCIATING)) {
5476 IPW_DEBUG_ASSOC("Disassociating due to BSSID change.\n");
5477 ipw_disassociate(priv);
5478 } else {
5479 ipw_associate(priv);
5480 }
5481
5482 return 0;
5483}
5484
5485static int ipw_wx_get_wap(struct net_device *dev,
5486 struct iw_request_info *info,
5487 union iwreq_data *wrqu, char *extra)
5488{
5489 struct ipw_priv *priv = ieee80211_priv(dev);
5490 /* If we are associated, trying to associate, or have a statically
5491 * configured BSSID then return that; otherwise return ANY */
5492 if (priv->config & CFG_STATIC_BSSID ||
5493 priv->status & (STATUS_ASSOCIATED | STATUS_ASSOCIATING)) {
5494 wrqu->ap_addr.sa_family = ARPHRD_ETHER;
5495 memcpy(wrqu->ap_addr.sa_data, &priv->bssid, ETH_ALEN);
5496 } else
5497 memset(wrqu->ap_addr.sa_data, 0, ETH_ALEN);
5498
5499 IPW_DEBUG_WX("Getting WAP BSSID: " MAC_FMT "\n",
5500 MAC_ARG(wrqu->ap_addr.sa_data));
5501 return 0;
5502}
5503
5504static int ipw_wx_set_essid(struct net_device *dev,
5505 struct iw_request_info *info,
5506 union iwreq_data *wrqu, char *extra)
5507{
5508 struct ipw_priv *priv = ieee80211_priv(dev);
5509 char *essid = ""; /* ANY */
5510 int length = 0;
5511
5512 if (wrqu->essid.flags && wrqu->essid.length) {
5513 length = wrqu->essid.length - 1;
5514 essid = extra;
5515 }
5516 if (length == 0) {
5517 IPW_DEBUG_WX("Setting ESSID to ANY\n");
5518 priv->config &= ~CFG_STATIC_ESSID;
5519 if (!(priv->status & (STATUS_SCANNING | STATUS_ASSOCIATED |
5520 STATUS_ASSOCIATING))) {
5521 IPW_DEBUG_ASSOC("Attempting to associate with new "
5522 "parameters.\n");
5523 ipw_associate(priv);
5524 }
5525
5526 return 0;
5527 }
5528
5529 length = min(length, IW_ESSID_MAX_SIZE);
5530
5531 priv->config |= CFG_STATIC_ESSID;
5532
5533 if (priv->essid_len == length && !memcmp(priv->essid, extra, length)) {
5534 IPW_DEBUG_WX("ESSID set to current ESSID.\n");
5535 return 0;
5536 }
5537
5538 IPW_DEBUG_WX("Setting ESSID: '%s' (%d)\n", escape_essid(essid, length),
5539 length);
5540
5541 priv->essid_len = length;
5542 memcpy(priv->essid, essid, priv->essid_len);
5543
5544 /* If we are currently associated, or trying to associate
5545 * then see if this is a new ESSID (causing us to disassociate) */
5546 if (priv->status & (STATUS_ASSOCIATED | STATUS_ASSOCIATING)) {
5547 IPW_DEBUG_ASSOC("Disassociating due to ESSID change.\n");
5548 ipw_disassociate(priv);
5549 } else {
5550 ipw_associate(priv);
5551 }
5552
5553 return 0;
5554}
5555
5556static int ipw_wx_get_essid(struct net_device *dev,
5557 struct iw_request_info *info,
5558 union iwreq_data *wrqu, char *extra)
5559{
5560 struct ipw_priv *priv = ieee80211_priv(dev);
5561
5562 /* If we are associated, trying to associate, or have a statically
5563 * configured ESSID then return that; otherwise return ANY */
5564 if (priv->config & CFG_STATIC_ESSID ||
5565 priv->status & (STATUS_ASSOCIATED | STATUS_ASSOCIATING)) {
5566 IPW_DEBUG_WX("Getting essid: '%s'\n",
5567 escape_essid(priv->essid, priv->essid_len));
5568 memcpy(extra, priv->essid, priv->essid_len);
5569 wrqu->essid.length = priv->essid_len;
5570 wrqu->essid.flags = 1; /* active */
5571 } else {
5572 IPW_DEBUG_WX("Getting essid: ANY\n");
5573 wrqu->essid.length = 0;
5574 wrqu->essid.flags = 0; /* active */
5575 }
5576
5577 return 0;
5578}
5579
5580static int ipw_wx_set_nick(struct net_device *dev,
5581 struct iw_request_info *info,
5582 union iwreq_data *wrqu, char *extra)
5583{
5584 struct ipw_priv *priv = ieee80211_priv(dev);
5585
5586 IPW_DEBUG_WX("Setting nick to '%s'\n", extra);
5587 if (wrqu->data.length > IW_ESSID_MAX_SIZE)
5588 return -E2BIG;
5589
5590 wrqu->data.length = min((size_t)wrqu->data.length, sizeof(priv->nick));
5591 memset(priv->nick, 0, sizeof(priv->nick));
5592 memcpy(priv->nick, extra, wrqu->data.length);
5593 IPW_DEBUG_TRACE("<<\n");
5594 return 0;
5595
5596}
5597
5598
5599static int ipw_wx_get_nick(struct net_device *dev,
5600 struct iw_request_info *info,
5601 union iwreq_data *wrqu, char *extra)
5602{
5603 struct ipw_priv *priv = ieee80211_priv(dev);
5604 IPW_DEBUG_WX("Getting nick\n");
5605 wrqu->data.length = strlen(priv->nick) + 1;
5606 memcpy(extra, priv->nick, wrqu->data.length);
5607 wrqu->data.flags = 1; /* active */
5608 return 0;
5609}
5610
5611
5612static int ipw_wx_set_rate(struct net_device *dev,
5613 struct iw_request_info *info,
5614 union iwreq_data *wrqu, char *extra)
5615{
5616 IPW_DEBUG_WX("0x%p, 0x%p, 0x%p\n", dev, info, wrqu);
5617 return -EOPNOTSUPP;
5618}
5619
5620static int ipw_wx_get_rate(struct net_device *dev,
5621 struct iw_request_info *info,
5622 union iwreq_data *wrqu, char *extra)
5623{
5624 struct ipw_priv * priv = ieee80211_priv(dev);
5625 wrqu->bitrate.value = priv->last_rate;
5626
5627 IPW_DEBUG_WX("GET Rate -> %d \n", wrqu->bitrate.value);
5628 return 0;
5629}
5630
5631
5632static int ipw_wx_set_rts(struct net_device *dev,
5633 struct iw_request_info *info,
5634 union iwreq_data *wrqu, char *extra)
5635{
5636 struct ipw_priv *priv = ieee80211_priv(dev);
5637
5638 if (wrqu->rts.disabled)
5639 priv->rts_threshold = DEFAULT_RTS_THRESHOLD;
5640 else {
5641 if (wrqu->rts.value < MIN_RTS_THRESHOLD ||
5642 wrqu->rts.value > MAX_RTS_THRESHOLD)
5643 return -EINVAL;
5644
5645 priv->rts_threshold = wrqu->rts.value;
5646 }
5647
5648 ipw_send_rts_threshold(priv, priv->rts_threshold);
5649 IPW_DEBUG_WX("SET RTS Threshold -> %d \n", priv->rts_threshold);
5650 return 0;
5651}
5652
5653static int ipw_wx_get_rts(struct net_device *dev,
5654 struct iw_request_info *info,
5655 union iwreq_data *wrqu, char *extra)
5656{
5657 struct ipw_priv *priv = ieee80211_priv(dev);
5658 wrqu->rts.value = priv->rts_threshold;
5659 wrqu->rts.fixed = 0; /* no auto select */
5660 wrqu->rts.disabled =
5661 (wrqu->rts.value == DEFAULT_RTS_THRESHOLD);
5662
5663 IPW_DEBUG_WX("GET RTS Threshold -> %d \n", wrqu->rts.value);
5664 return 0;
5665}
5666
5667
5668static int ipw_wx_set_txpow(struct net_device *dev,
5669 struct iw_request_info *info,
5670 union iwreq_data *wrqu, char *extra)
5671{
5672 struct ipw_priv *priv = ieee80211_priv(dev);
5673 struct ipw_tx_power tx_power;
5674 int i;
5675
5676 if (ipw_radio_kill_sw(priv, wrqu->power.disabled))
5677 return -EINPROGRESS;
5678
5679 if (wrqu->power.flags != IW_TXPOW_DBM)
5680 return -EINVAL;
5681
5682 if ((wrqu->power.value > 20) ||
5683 (wrqu->power.value < -12))
5684 return -EINVAL;
5685
5686 priv->tx_power = wrqu->power.value;
5687
5688 memset(&tx_power, 0, sizeof(tx_power));
5689
5690 /* configure device for 'G' band */
5691 tx_power.ieee_mode = IPW_G_MODE;
5692 tx_power.num_channels = 11;
5693 for (i = 0; i < 11; i++) {
5694 tx_power.channels_tx_power[i].channel_number = i + 1;
5695 tx_power.channels_tx_power[i].tx_power = priv->tx_power;
5696 }
5697 if (ipw_send_tx_power(priv, &tx_power))
5698 goto error;
5699
5700 /* configure device to also handle 'B' band */
5701 tx_power.ieee_mode = IPW_B_MODE;
5702 if (ipw_send_tx_power(priv, &tx_power))
5703 goto error;
5704
5705 return 0;
5706
5707 error:
5708 return -EIO;
5709}
5710
5711
5712static int ipw_wx_get_txpow(struct net_device *dev,
5713 struct iw_request_info *info,
5714 union iwreq_data *wrqu, char *extra)
5715{
5716 struct ipw_priv *priv = ieee80211_priv(dev);
5717
5718 wrqu->power.value = priv->tx_power;
5719 wrqu->power.fixed = 1;
5720 wrqu->power.flags = IW_TXPOW_DBM;
5721 wrqu->power.disabled = (priv->status & STATUS_RF_KILL_MASK) ? 1 : 0;
5722
5723 IPW_DEBUG_WX("GET TX Power -> %s %d \n",
5724 wrqu->power.disabled ? "ON" : "OFF",
5725 wrqu->power.value);
5726
5727 return 0;
5728}
5729
5730static int ipw_wx_set_frag(struct net_device *dev,
5731 struct iw_request_info *info,
5732 union iwreq_data *wrqu, char *extra)
5733{
5734 struct ipw_priv *priv = ieee80211_priv(dev);
5735
5736 if (wrqu->frag.disabled)
5737 priv->ieee->fts = DEFAULT_FTS;
5738 else {
5739 if (wrqu->frag.value < MIN_FRAG_THRESHOLD ||
5740 wrqu->frag.value > MAX_FRAG_THRESHOLD)
5741 return -EINVAL;
5742
5743 priv->ieee->fts = wrqu->frag.value & ~0x1;
5744 }
5745
5746 ipw_send_frag_threshold(priv, wrqu->frag.value);
5747 IPW_DEBUG_WX("SET Frag Threshold -> %d \n", wrqu->frag.value);
5748 return 0;
5749}
5750
5751static int ipw_wx_get_frag(struct net_device *dev,
5752 struct iw_request_info *info,
5753 union iwreq_data *wrqu, char *extra)
5754{
5755 struct ipw_priv *priv = ieee80211_priv(dev);
5756 wrqu->frag.value = priv->ieee->fts;
5757 wrqu->frag.fixed = 0; /* no auto select */
5758 wrqu->frag.disabled =
5759 (wrqu->frag.value == DEFAULT_FTS);
5760
5761 IPW_DEBUG_WX("GET Frag Threshold -> %d \n", wrqu->frag.value);
5762
5763 return 0;
5764}
5765
5766static int ipw_wx_set_retry(struct net_device *dev,
5767 struct iw_request_info *info,
5768 union iwreq_data *wrqu, char *extra)
5769{
5770 IPW_DEBUG_WX("0x%p, 0x%p, 0x%p\n", dev, info, wrqu);
5771 return -EOPNOTSUPP;
5772}
5773
5774
5775static int ipw_wx_get_retry(struct net_device *dev,
5776 struct iw_request_info *info,
5777 union iwreq_data *wrqu, char *extra)
5778{
5779 IPW_DEBUG_WX("0x%p, 0x%p, 0x%p\n", dev, info, wrqu);
5780 return -EOPNOTSUPP;
5781}
5782
5783
5784static int ipw_wx_set_scan(struct net_device *dev,
5785 struct iw_request_info *info,
5786 union iwreq_data *wrqu, char *extra)
5787{
5788 struct ipw_priv *priv = ieee80211_priv(dev);
5789 IPW_DEBUG_WX("Start scan\n");
5790 if (ipw_request_scan(priv))
5791 return -EIO;
5792 return 0;
5793}
5794
5795static int ipw_wx_get_scan(struct net_device *dev,
5796 struct iw_request_info *info,
5797 union iwreq_data *wrqu, char *extra)
5798{
5799 struct ipw_priv *priv = ieee80211_priv(dev);
5800 return ieee80211_wx_get_scan(priv->ieee, info, wrqu, extra);
5801}
5802
5803static int ipw_wx_set_encode(struct net_device *dev,
5804 struct iw_request_info *info,
5805 union iwreq_data *wrqu, char *key)
5806{
5807 struct ipw_priv *priv = ieee80211_priv(dev);
5808 return ieee80211_wx_set_encode(priv->ieee, info, wrqu, key);
5809}
5810
5811static int ipw_wx_get_encode(struct net_device *dev,
5812 struct iw_request_info *info,
5813 union iwreq_data *wrqu, char *key)
5814{
5815 struct ipw_priv *priv = ieee80211_priv(dev);
5816 return ieee80211_wx_get_encode(priv->ieee, info, wrqu, key);
5817}
5818
5819static int ipw_wx_set_power(struct net_device *dev,
5820 struct iw_request_info *info,
5821 union iwreq_data *wrqu, char *extra)
5822{
5823 struct ipw_priv *priv = ieee80211_priv(dev);
5824 int err;
5825
5826 if (wrqu->power.disabled) {
5827 priv->power_mode = IPW_POWER_LEVEL(priv->power_mode);
5828 err = ipw_send_power_mode(priv, IPW_POWER_MODE_CAM);
5829 if (err) {
5830 IPW_DEBUG_WX("failed setting power mode.\n");
5831 return err;
5832 }
5833
5834 IPW_DEBUG_WX("SET Power Management Mode -> off\n");
5835
5836 return 0;
5837 }
5838
5839 switch (wrqu->power.flags & IW_POWER_MODE) {
5840 case IW_POWER_ON: /* If not specified */
5841 case IW_POWER_MODE: /* If set all mask */
5842 case IW_POWER_ALL_R: /* If explicitely state all */
5843 break;
5844 default: /* Otherwise we don't support it */
5845 IPW_DEBUG_WX("SET PM Mode: %X not supported.\n",
5846 wrqu->power.flags);
5847 return -EOPNOTSUPP;
5848 }
5849
5850 /* If the user hasn't specified a power management mode yet, default
5851 * to BATTERY */
5852 if (IPW_POWER_LEVEL(priv->power_mode) == IPW_POWER_AC)
5853 priv->power_mode = IPW_POWER_ENABLED | IPW_POWER_BATTERY;
5854 else
5855 priv->power_mode = IPW_POWER_ENABLED | priv->power_mode;
5856 err = ipw_send_power_mode(priv, IPW_POWER_LEVEL(priv->power_mode));
5857 if (err) {
5858 IPW_DEBUG_WX("failed setting power mode.\n");
5859 return err;
5860 }
5861
5862 IPW_DEBUG_WX("SET Power Management Mode -> 0x%02X\n",
5863 priv->power_mode);
5864
5865 return 0;
5866}
5867
5868static int ipw_wx_get_power(struct net_device *dev,
5869 struct iw_request_info *info,
5870 union iwreq_data *wrqu, char *extra)
5871{
5872 struct ipw_priv *priv = ieee80211_priv(dev);
5873
5874 if (!(priv->power_mode & IPW_POWER_ENABLED)) {
5875 wrqu->power.disabled = 1;
5876 } else {
5877 wrqu->power.disabled = 0;
5878 }
5879
5880 IPW_DEBUG_WX("GET Power Management Mode -> %02X\n", priv->power_mode);
5881
5882 return 0;
5883}
5884
5885static int ipw_wx_set_powermode(struct net_device *dev,
5886 struct iw_request_info *info,
5887 union iwreq_data *wrqu, char *extra)
5888{
5889 struct ipw_priv *priv = ieee80211_priv(dev);
5890 int mode = *(int *)extra;
5891 int err;
5892
5893 if ((mode < 1) || (mode > IPW_POWER_LIMIT)) {
5894 mode = IPW_POWER_AC;
5895 priv->power_mode = mode;
5896 } else {
5897 priv->power_mode = IPW_POWER_ENABLED | mode;
5898 }
5899
5900 if (priv->power_mode != mode) {
5901 err = ipw_send_power_mode(priv, mode);
5902
5903 if (err) {
5904 IPW_DEBUG_WX("failed setting power mode.\n");
5905 return err;
5906 }
5907 }
5908
5909 return 0;
5910}
5911
5912#define MAX_WX_STRING 80
5913static int ipw_wx_get_powermode(struct net_device *dev,
5914 struct iw_request_info *info,
5915 union iwreq_data *wrqu, char *extra)
5916{
5917 struct ipw_priv *priv = ieee80211_priv(dev);
5918 int level = IPW_POWER_LEVEL(priv->power_mode);
5919 char *p = extra;
5920
5921 p += snprintf(p, MAX_WX_STRING, "Power save level: %d ", level);
5922
5923 switch (level) {
5924 case IPW_POWER_AC:
5925 p += snprintf(p, MAX_WX_STRING - (p - extra), "(AC)");
5926 break;
5927 case IPW_POWER_BATTERY:
5928 p += snprintf(p, MAX_WX_STRING - (p - extra), "(BATTERY)");
5929 break;
5930 default:
5931 p += snprintf(p, MAX_WX_STRING - (p - extra),
5932 "(Timeout %dms, Period %dms)",
5933 timeout_duration[level - 1] / 1000,
5934 period_duration[level - 1] / 1000);
5935 }
5936
5937 if (!(priv->power_mode & IPW_POWER_ENABLED))
5938 p += snprintf(p, MAX_WX_STRING - (p - extra)," OFF");
5939
5940 wrqu->data.length = p - extra + 1;
5941
5942 return 0;
5943}
5944
5945static int ipw_wx_set_wireless_mode(struct net_device *dev,
5946 struct iw_request_info *info,
5947 union iwreq_data *wrqu, char *extra)
5948{
5949 struct ipw_priv *priv = ieee80211_priv(dev);
5950 int mode = *(int *)extra;
5951 u8 band = 0, modulation = 0;
5952
5953 if (mode == 0 || mode & ~IEEE_MODE_MASK) {
5954 IPW_WARNING("Attempt to set invalid wireless mode: %d\n",
5955 mode);
5956 return -EINVAL;
5957 }
5958
5959 if (priv->adapter == IPW_2915ABG) {
5960 priv->ieee->abg_ture = 1;
5961 if (mode & IEEE_A) {
5962 band |= IEEE80211_52GHZ_BAND;
5963 modulation |= IEEE80211_OFDM_MODULATION;
5964 } else
5965 priv->ieee->abg_ture = 0;
5966 } else {
5967 if (mode & IEEE_A) {
5968 IPW_WARNING("Attempt to set 2200BG into "
5969 "802.11a mode\n");
5970 return -EINVAL;
5971 }
5972
5973 priv->ieee->abg_ture = 0;
5974 }
5975
5976 if (mode & IEEE_B) {
5977 band |= IEEE80211_24GHZ_BAND;
5978 modulation |= IEEE80211_CCK_MODULATION;
5979 } else
5980 priv->ieee->abg_ture = 0;
5981
5982 if (mode & IEEE_G) {
5983 band |= IEEE80211_24GHZ_BAND;
5984 modulation |= IEEE80211_OFDM_MODULATION;
5985 } else
5986 priv->ieee->abg_ture = 0;
5987
5988 priv->ieee->mode = mode;
5989 priv->ieee->freq_band = band;
5990 priv->ieee->modulation = modulation;
5991 init_supported_rates(priv, &priv->rates);
5992
5993 /* If we are currently associated, or trying to associate
5994 * then see if this is a new configuration (causing us to
5995 * disassociate) */
5996 if (priv->status & (STATUS_ASSOCIATED | STATUS_ASSOCIATING)) {
5997 /* The resulting association will trigger
5998 * the new rates to be sent to the device */
5999 IPW_DEBUG_ASSOC("Disassociating due to mode change.\n");
6000 ipw_disassociate(priv);
6001 } else
6002 ipw_send_supported_rates(priv, &priv->rates);
6003
6004 IPW_DEBUG_WX("PRIV SET MODE: %c%c%c\n",
6005 mode & IEEE_A ? 'a' : '.',
6006 mode & IEEE_B ? 'b' : '.',
6007 mode & IEEE_G ? 'g' : '.');
6008 return 0;
6009}
6010
6011static int ipw_wx_get_wireless_mode(struct net_device *dev,
6012 struct iw_request_info *info,
6013 union iwreq_data *wrqu, char *extra)
6014{
6015 struct ipw_priv *priv = ieee80211_priv(dev);
6016
6017 switch (priv->ieee->freq_band) {
6018 case IEEE80211_24GHZ_BAND:
6019 switch (priv->ieee->modulation) {
6020 case IEEE80211_CCK_MODULATION:
6021 strncpy(extra, "802.11b (2)", MAX_WX_STRING);
6022 break;
6023 case IEEE80211_OFDM_MODULATION:
6024 strncpy(extra, "802.11g (4)", MAX_WX_STRING);
6025 break;
6026 default:
6027 strncpy(extra, "802.11bg (6)", MAX_WX_STRING);
6028 break;
6029 }
6030 break;
6031
6032 case IEEE80211_52GHZ_BAND:
6033 strncpy(extra, "802.11a (1)", MAX_WX_STRING);
6034 break;
6035
6036 default: /* Mixed Band */
6037 switch (priv->ieee->modulation) {
6038 case IEEE80211_CCK_MODULATION:
6039 strncpy(extra, "802.11ab (3)", MAX_WX_STRING);
6040 break;
6041 case IEEE80211_OFDM_MODULATION:
6042 strncpy(extra, "802.11ag (5)", MAX_WX_STRING);
6043 break;
6044 default:
6045 strncpy(extra, "802.11abg (7)", MAX_WX_STRING);
6046 break;
6047 }
6048 break;
6049 }
6050
6051 IPW_DEBUG_WX("PRIV GET MODE: %s\n", extra);
6052
6053 wrqu->data.length = strlen(extra) + 1;
6054
6055 return 0;
6056}
6057
6058#ifdef CONFIG_IPW_PROMISC
6059static int ipw_wx_set_promisc(struct net_device *dev,
6060 struct iw_request_info *info,
6061 union iwreq_data *wrqu, char *extra)
6062{
6063 struct ipw_priv *priv = ieee80211_priv(dev);
6064 int *parms = (int *)extra;
6065 int enable = (parms[0] > 0);
6066
6067 IPW_DEBUG_WX("SET PROMISC: %d %d\n", enable, parms[1]);
6068 if (enable) {
6069 if (priv->ieee->iw_mode != IW_MODE_MONITOR) {
6070 priv->net_dev->type = ARPHRD_IEEE80211;
6071 ipw_adapter_restart(priv);
6072 }
6073
6074 ipw_set_channel(priv, parms[1]);
6075 } else {
6076 if (priv->ieee->iw_mode != IW_MODE_MONITOR)
6077 return 0;
6078 priv->net_dev->type = ARPHRD_ETHER;
6079 ipw_adapter_restart(priv);
6080 }
6081 return 0;
6082}
6083
6084
6085static int ipw_wx_reset(struct net_device *dev,
6086 struct iw_request_info *info,
6087 union iwreq_data *wrqu, char *extra)
6088{
6089 struct ipw_priv *priv = ieee80211_priv(dev);
6090 IPW_DEBUG_WX("RESET\n");
6091 ipw_adapter_restart(priv);
6092 return 0;
6093}
6094#endif // CONFIG_IPW_PROMISC
6095
6096/* Rebase the WE IOCTLs to zero for the handler array */
6097#define IW_IOCTL(x) [(x)-SIOCSIWCOMMIT]
6098static iw_handler ipw_wx_handlers[] =
6099{
6100 IW_IOCTL(SIOCGIWNAME) = ipw_wx_get_name,
6101 IW_IOCTL(SIOCSIWFREQ) = ipw_wx_set_freq,
6102 IW_IOCTL(SIOCGIWFREQ) = ipw_wx_get_freq,
6103 IW_IOCTL(SIOCSIWMODE) = ipw_wx_set_mode,
6104 IW_IOCTL(SIOCGIWMODE) = ipw_wx_get_mode,
6105 IW_IOCTL(SIOCGIWRANGE) = ipw_wx_get_range,
6106 IW_IOCTL(SIOCSIWAP) = ipw_wx_set_wap,
6107 IW_IOCTL(SIOCGIWAP) = ipw_wx_get_wap,
6108 IW_IOCTL(SIOCSIWSCAN) = ipw_wx_set_scan,
6109 IW_IOCTL(SIOCGIWSCAN) = ipw_wx_get_scan,
6110 IW_IOCTL(SIOCSIWESSID) = ipw_wx_set_essid,
6111 IW_IOCTL(SIOCGIWESSID) = ipw_wx_get_essid,
6112 IW_IOCTL(SIOCSIWNICKN) = ipw_wx_set_nick,
6113 IW_IOCTL(SIOCGIWNICKN) = ipw_wx_get_nick,
6114 IW_IOCTL(SIOCSIWRATE) = ipw_wx_set_rate,
6115 IW_IOCTL(SIOCGIWRATE) = ipw_wx_get_rate,
6116 IW_IOCTL(SIOCSIWRTS) = ipw_wx_set_rts,
6117 IW_IOCTL(SIOCGIWRTS) = ipw_wx_get_rts,
6118 IW_IOCTL(SIOCSIWFRAG) = ipw_wx_set_frag,
6119 IW_IOCTL(SIOCGIWFRAG) = ipw_wx_get_frag,
6120 IW_IOCTL(SIOCSIWTXPOW) = ipw_wx_set_txpow,
6121 IW_IOCTL(SIOCGIWTXPOW) = ipw_wx_get_txpow,
6122 IW_IOCTL(SIOCSIWRETRY) = ipw_wx_set_retry,
6123 IW_IOCTL(SIOCGIWRETRY) = ipw_wx_get_retry,
6124 IW_IOCTL(SIOCSIWENCODE) = ipw_wx_set_encode,
6125 IW_IOCTL(SIOCGIWENCODE) = ipw_wx_get_encode,
6126 IW_IOCTL(SIOCSIWPOWER) = ipw_wx_set_power,
6127 IW_IOCTL(SIOCGIWPOWER) = ipw_wx_get_power,
6128};
6129
6130#define IPW_PRIV_SET_POWER SIOCIWFIRSTPRIV
6131#define IPW_PRIV_GET_POWER SIOCIWFIRSTPRIV+1
6132#define IPW_PRIV_SET_MODE SIOCIWFIRSTPRIV+2
6133#define IPW_PRIV_GET_MODE SIOCIWFIRSTPRIV+3
6134#define IPW_PRIV_SET_PROMISC SIOCIWFIRSTPRIV+4
6135#define IPW_PRIV_RESET SIOCIWFIRSTPRIV+5
6136
6137
6138static struct iw_priv_args ipw_priv_args[] = {
6139 {
6140 .cmd = IPW_PRIV_SET_POWER,
6141 .set_args = IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
6142 .name = "set_power"
6143 },
6144 {
6145 .cmd = IPW_PRIV_GET_POWER,
6146 .get_args = IW_PRIV_TYPE_CHAR | IW_PRIV_SIZE_FIXED | MAX_WX_STRING,
6147 .name = "get_power"
6148 },
6149 {
6150 .cmd = IPW_PRIV_SET_MODE,
6151 .set_args = IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
6152 .name = "set_mode"
6153 },
6154 {
6155 .cmd = IPW_PRIV_GET_MODE,
6156 .get_args = IW_PRIV_TYPE_CHAR | IW_PRIV_SIZE_FIXED | MAX_WX_STRING,
6157 .name = "get_mode"
6158 },
6159#ifdef CONFIG_IPW_PROMISC
6160 {
6161 IPW_PRIV_SET_PROMISC,
6162 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 2, 0, "monitor"
6163 },
6164 {
6165 IPW_PRIV_RESET,
6166 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 0, 0, "reset"
6167 },
6168#endif /* CONFIG_IPW_PROMISC */
6169};
6170
6171static iw_handler ipw_priv_handler[] = {
6172 ipw_wx_set_powermode,
6173 ipw_wx_get_powermode,
6174 ipw_wx_set_wireless_mode,
6175 ipw_wx_get_wireless_mode,
6176#ifdef CONFIG_IPW_PROMISC
6177 ipw_wx_set_promisc,
6178 ipw_wx_reset,
6179#endif
6180};
6181
6182static struct iw_handler_def ipw_wx_handler_def =
6183{
6184 .standard = ipw_wx_handlers,
6185 .num_standard = ARRAY_SIZE(ipw_wx_handlers),
6186 .num_private = ARRAY_SIZE(ipw_priv_handler),
6187 .num_private_args = ARRAY_SIZE(ipw_priv_args),
6188 .private = ipw_priv_handler,
6189 .private_args = ipw_priv_args,
6190};
6191
6192
6193
6194
6195/*
6196 * Get wireless statistics.
6197 * Called by /proc/net/wireless
6198 * Also called by SIOCGIWSTATS
6199 */
6200static struct iw_statistics *ipw_get_wireless_stats(struct net_device * dev)
6201{
6202 struct ipw_priv *priv = ieee80211_priv(dev);
6203 struct iw_statistics *wstats;
6204
6205 wstats = &priv->wstats;
6206
6207 /* if hw is disabled, then ipw2100_get_ordinal() can't be called.
6208 * ipw2100_wx_wireless_stats seems to be called before fw is
6209 * initialized. STATUS_ASSOCIATED will only be set if the hw is up
6210 * and associated; if not associcated, the values are all meaningless
6211 * anyway, so set them all to NULL and INVALID */
6212 if (!(priv->status & STATUS_ASSOCIATED)) {
6213 wstats->miss.beacon = 0;
6214 wstats->discard.retries = 0;
6215 wstats->qual.qual = 0;
6216 wstats->qual.level = 0;
6217 wstats->qual.noise = 0;
6218 wstats->qual.updated = 7;
6219 wstats->qual.updated |= IW_QUAL_NOISE_INVALID |
6220 IW_QUAL_QUAL_INVALID | IW_QUAL_LEVEL_INVALID;
6221 return wstats;
6222 }
6223
6224 wstats->qual.qual = priv->quality;
6225 wstats->qual.level = average_value(&priv->average_rssi);
6226 wstats->qual.noise = average_value(&priv->average_noise);
6227 wstats->qual.updated = IW_QUAL_QUAL_UPDATED | IW_QUAL_LEVEL_UPDATED |
6228 IW_QUAL_NOISE_UPDATED;
6229
6230 wstats->miss.beacon = average_value(&priv->average_missed_beacons);
6231 wstats->discard.retries = priv->last_tx_failures;
6232 wstats->discard.code = priv->ieee->ieee_stats.rx_discards_undecryptable;
6233
6234/* if (ipw_get_ordinal(priv, IPW_ORD_STAT_TX_RETRY, &tx_retry, &len))
6235 goto fail_get_ordinal;
6236 wstats->discard.retries += tx_retry; */
6237
6238 return wstats;
6239}
6240
6241
6242/* net device stuff */
6243
6244static inline void init_sys_config(struct ipw_sys_config *sys_config)
6245{
6246 memset(sys_config, 0, sizeof(struct ipw_sys_config));
6247 sys_config->bt_coexistence = 1; /* We may need to look into prvStaBtConfig */
6248 sys_config->answer_broadcast_ssid_probe = 0;
6249 sys_config->accept_all_data_frames = 0;
6250 sys_config->accept_non_directed_frames = 1;
6251 sys_config->exclude_unicast_unencrypted = 0;
6252 sys_config->disable_unicast_decryption = 1;
6253 sys_config->exclude_multicast_unencrypted = 0;
6254 sys_config->disable_multicast_decryption = 1;
6255 sys_config->antenna_diversity = CFG_SYS_ANTENNA_BOTH;
6256 sys_config->pass_crc_to_host = 0; /* TODO: See if 1 gives us FCS */
6257 sys_config->dot11g_auto_detection = 0;
6258 sys_config->enable_cts_to_self = 0;
6259 sys_config->bt_coexist_collision_thr = 0;
6260 sys_config->pass_noise_stats_to_host = 1;
6261}
6262
6263static int ipw_net_open(struct net_device *dev)
6264{
6265 struct ipw_priv *priv = ieee80211_priv(dev);
6266 IPW_DEBUG_INFO("dev->open\n");
6267 /* we should be verifying the device is ready to be opened */
6268 if (!(priv->status & STATUS_RF_KILL_MASK) &&
6269 (priv->status & STATUS_ASSOCIATED))
6270 netif_start_queue(dev);
6271 return 0;
6272}
6273
6274static int ipw_net_stop(struct net_device *dev)
6275{
6276 IPW_DEBUG_INFO("dev->close\n");
6277 netif_stop_queue(dev);
6278 return 0;
6279}
6280
6281/*
6282todo:
6283
6284modify to send one tfd per fragment instead of using chunking. otherwise
6285we need to heavily modify the ieee80211_skb_to_txb.
6286*/
6287
6288static inline void ipw_tx_skb(struct ipw_priv *priv, struct ieee80211_txb *txb)
6289{
6290 struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)
6291 txb->fragments[0]->data;
6292 int i = 0;
6293 struct tfd_frame *tfd;
6294 struct clx2_tx_queue *txq = &priv->txq[0];
6295 struct clx2_queue *q = &txq->q;
6296 u8 id, hdr_len, unicast;
6297 u16 remaining_bytes;
6298
6299 switch (priv->ieee->iw_mode) {
6300 case IW_MODE_ADHOC:
6301 hdr_len = IEEE80211_3ADDR_LEN;
6302 unicast = !is_broadcast_ether_addr(hdr->addr1) &&
6303 !is_multicast_ether_addr(hdr->addr1);
6304 id = ipw_find_station(priv, hdr->addr1);
6305 if (id == IPW_INVALID_STATION) {
6306 id = ipw_add_station(priv, hdr->addr1);
6307 if (id == IPW_INVALID_STATION) {
6308 IPW_WARNING("Attempt to send data to "
6309 "invalid cell: " MAC_FMT "\n",
6310 MAC_ARG(hdr->addr1));
6311 goto drop;
6312 }
6313 }
6314 break;
6315
6316 case IW_MODE_INFRA:
6317 default:
6318 unicast = !is_broadcast_ether_addr(hdr->addr3) &&
6319 !is_multicast_ether_addr(hdr->addr3);
6320 hdr_len = IEEE80211_3ADDR_LEN;
6321 id = 0;
6322 break;
6323 }
6324
6325 tfd = &txq->bd[q->first_empty];
6326 txq->txb[q->first_empty] = txb;
6327 memset(tfd, 0, sizeof(*tfd));
6328 tfd->u.data.station_number = id;
6329
6330 tfd->control_flags.message_type = TX_FRAME_TYPE;
6331 tfd->control_flags.control_bits = TFD_NEED_IRQ_MASK;
6332
6333 tfd->u.data.cmd_id = DINO_CMD_TX;
6334 tfd->u.data.len = txb->payload_size;
6335 remaining_bytes = txb->payload_size;
6336 if (unlikely(!unicast))
6337 tfd->u.data.tx_flags = DCT_FLAG_NO_WEP;
6338 else
6339 tfd->u.data.tx_flags = DCT_FLAG_NO_WEP | DCT_FLAG_ACK_REQD;
6340
6341 if (priv->assoc_request.ieee_mode == IPW_B_MODE)
6342 tfd->u.data.tx_flags_ext = DCT_FLAG_EXT_MODE_CCK;
6343 else
6344 tfd->u.data.tx_flags_ext = DCT_FLAG_EXT_MODE_OFDM;
6345
6346 if (priv->config & CFG_PREAMBLE)
6347 tfd->u.data.tx_flags |= DCT_FLAG_SHORT_PREMBL;
6348
6349 memcpy(&tfd->u.data.tfd.tfd_24.mchdr, hdr, hdr_len);
6350
6351 /* payload */
6352 tfd->u.data.num_chunks = min((u8)(NUM_TFD_CHUNKS - 2), txb->nr_frags);
6353 for (i = 0; i < tfd->u.data.num_chunks; i++) {
6354 IPW_DEBUG_TX("Dumping TX packet frag %i of %i (%d bytes):\n",
6355 i, tfd->u.data.num_chunks,
6356 txb->fragments[i]->len - hdr_len);
6357 printk_buf(IPW_DL_TX, txb->fragments[i]->data + hdr_len,
6358 txb->fragments[i]->len - hdr_len);
6359
6360 tfd->u.data.chunk_ptr[i] = pci_map_single(
6361 priv->pci_dev, txb->fragments[i]->data + hdr_len,
6362 txb->fragments[i]->len - hdr_len, PCI_DMA_TODEVICE);
6363 tfd->u.data.chunk_len[i] = txb->fragments[i]->len - hdr_len;
6364 }
6365
6366 if (i != txb->nr_frags) {
6367 struct sk_buff *skb;
6368 u16 remaining_bytes = 0;
6369 int j;
6370
6371 for (j = i; j < txb->nr_frags; j++)
6372 remaining_bytes += txb->fragments[j]->len - hdr_len;
6373
6374 printk(KERN_INFO "Trying to reallocate for %d bytes\n",
6375 remaining_bytes);
6376 skb = alloc_skb(remaining_bytes, GFP_ATOMIC);
6377 if (skb != NULL) {
6378 tfd->u.data.chunk_len[i] = remaining_bytes;
6379 for (j = i; j < txb->nr_frags; j++) {
6380 int size = txb->fragments[j]->len - hdr_len;
6381 printk(KERN_INFO "Adding frag %d %d...\n",
6382 j, size);
6383 memcpy(skb_put(skb, size),
6384 txb->fragments[j]->data + hdr_len,
6385 size);
6386 }
6387 dev_kfree_skb_any(txb->fragments[i]);
6388 txb->fragments[i] = skb;
6389 tfd->u.data.chunk_ptr[i] = pci_map_single(
6390 priv->pci_dev, skb->data,
6391 tfd->u.data.chunk_len[i], PCI_DMA_TODEVICE);
6392 tfd->u.data.num_chunks++;
6393 }
6394 }
6395
6396 /* kick DMA */
6397 q->first_empty = ipw_queue_inc_wrap(q->first_empty, q->n_bd);
6398 ipw_write32(priv, q->reg_w, q->first_empty);
6399
6400 if (ipw_queue_space(q) < q->high_mark)
6401 netif_stop_queue(priv->net_dev);
6402
6403 return;
6404
6405 drop:
6406 IPW_DEBUG_DROP("Silently dropping Tx packet.\n");
6407 ieee80211_txb_free(txb);
6408}
6409
6410static int ipw_net_hard_start_xmit(struct ieee80211_txb *txb,
6411 struct net_device *dev)
6412{
6413 struct ipw_priv *priv = ieee80211_priv(dev);
6414 unsigned long flags;
6415
6416 IPW_DEBUG_TX("dev->xmit(%d bytes)\n", txb->payload_size);
6417
6418 spin_lock_irqsave(&priv->lock, flags);
6419
6420 if (!(priv->status & STATUS_ASSOCIATED)) {
6421 IPW_DEBUG_INFO("Tx attempt while not associated.\n");
6422 priv->ieee->stats.tx_carrier_errors++;
6423 netif_stop_queue(dev);
6424 goto fail_unlock;
6425 }
6426
6427 ipw_tx_skb(priv, txb);
6428
6429 spin_unlock_irqrestore(&priv->lock, flags);
6430 return 0;
6431
6432 fail_unlock:
6433 spin_unlock_irqrestore(&priv->lock, flags);
6434 return 1;
6435}
6436
6437static struct net_device_stats *ipw_net_get_stats(struct net_device *dev)
6438{
6439 struct ipw_priv *priv = ieee80211_priv(dev);
6440
6441 priv->ieee->stats.tx_packets = priv->tx_packets;
6442 priv->ieee->stats.rx_packets = priv->rx_packets;
6443 return &priv->ieee->stats;
6444}
6445
6446static void ipw_net_set_multicast_list(struct net_device *dev)
6447{
6448
6449}
6450
6451static int ipw_net_set_mac_address(struct net_device *dev, void *p)
6452{
6453 struct ipw_priv *priv = ieee80211_priv(dev);
6454 struct sockaddr *addr = p;
6455 if (!is_valid_ether_addr(addr->sa_data))
6456 return -EADDRNOTAVAIL;
6457 priv->config |= CFG_CUSTOM_MAC;
6458 memcpy(priv->mac_addr, addr->sa_data, ETH_ALEN);
6459 printk(KERN_INFO "%s: Setting MAC to " MAC_FMT "\n",
6460 priv->net_dev->name, MAC_ARG(priv->mac_addr));
6461 ipw_adapter_restart(priv);
6462 return 0;
6463}
6464
6465static void ipw_ethtool_get_drvinfo(struct net_device *dev,
6466 struct ethtool_drvinfo *info)
6467{
6468 struct ipw_priv *p = ieee80211_priv(dev);
6469 char vers[64];
6470 char date[32];
6471 u32 len;
6472
6473 strcpy(info->driver, DRV_NAME);
6474 strcpy(info->version, DRV_VERSION);
6475
6476 len = sizeof(vers);
6477 ipw_get_ordinal(p, IPW_ORD_STAT_FW_VERSION, vers, &len);
6478 len = sizeof(date);
6479 ipw_get_ordinal(p, IPW_ORD_STAT_FW_DATE, date, &len);
6480
6481 snprintf(info->fw_version, sizeof(info->fw_version),"%s (%s)",
6482 vers, date);
6483 strcpy(info->bus_info, pci_name(p->pci_dev));
6484 info->eedump_len = CX2_EEPROM_IMAGE_SIZE;
6485}
6486
6487static u32 ipw_ethtool_get_link(struct net_device *dev)
6488{
6489 struct ipw_priv *priv = ieee80211_priv(dev);
6490 return (priv->status & STATUS_ASSOCIATED) != 0;
6491}
6492
6493static int ipw_ethtool_get_eeprom_len(struct net_device *dev)
6494{
6495 return CX2_EEPROM_IMAGE_SIZE;
6496}
6497
6498static int ipw_ethtool_get_eeprom(struct net_device *dev,
6499 struct ethtool_eeprom *eeprom, u8 *bytes)
6500{
6501 struct ipw_priv *p = ieee80211_priv(dev);
6502
6503 if (eeprom->offset + eeprom->len > CX2_EEPROM_IMAGE_SIZE)
6504 return -EINVAL;
6505
6506 memcpy(bytes, &((u8 *)p->eeprom)[eeprom->offset], eeprom->len);
6507 return 0;
6508}
6509
6510static int ipw_ethtool_set_eeprom(struct net_device *dev,
6511 struct ethtool_eeprom *eeprom, u8 *bytes)
6512{
6513 struct ipw_priv *p = ieee80211_priv(dev);
6514 int i;
6515
6516 if (eeprom->offset + eeprom->len > CX2_EEPROM_IMAGE_SIZE)
6517 return -EINVAL;
6518
6519 memcpy(&((u8 *)p->eeprom)[eeprom->offset], bytes, eeprom->len);
6520 for (i = IPW_EEPROM_DATA;
6521 i < IPW_EEPROM_DATA + CX2_EEPROM_IMAGE_SIZE;
6522 i++)
6523 ipw_write8(p, i, p->eeprom[i]);
6524
6525 return 0;
6526}
6527
6528static struct ethtool_ops ipw_ethtool_ops = {
6529 .get_link = ipw_ethtool_get_link,
6530 .get_drvinfo = ipw_ethtool_get_drvinfo,
6531 .get_eeprom_len = ipw_ethtool_get_eeprom_len,
6532 .get_eeprom = ipw_ethtool_get_eeprom,
6533 .set_eeprom = ipw_ethtool_set_eeprom,
6534};
6535
6536static irqreturn_t ipw_isr(int irq, void *data, struct pt_regs *regs)
6537{
6538 struct ipw_priv *priv = data;
6539 u32 inta, inta_mask;
6540
6541 if (!priv)
6542 return IRQ_NONE;
6543
6544 spin_lock(&priv->lock);
6545
6546 if (!(priv->status & STATUS_INT_ENABLED)) {
6547 /* Shared IRQ */
6548 goto none;
6549 }
6550
6551 inta = ipw_read32(priv, CX2_INTA_RW);
6552 inta_mask = ipw_read32(priv, CX2_INTA_MASK_R);
6553
6554 if (inta == 0xFFFFFFFF) {
6555 /* Hardware disappeared */
6556 IPW_WARNING("IRQ INTA == 0xFFFFFFFF\n");
6557 goto none;
6558 }
6559
6560 if (!(inta & (CX2_INTA_MASK_ALL & inta_mask))) {
6561 /* Shared interrupt */
6562 goto none;
6563 }
6564
6565 /* tell the device to stop sending interrupts */
6566 ipw_disable_interrupts(priv);
6567
6568 /* ack current interrupts */
6569 inta &= (CX2_INTA_MASK_ALL & inta_mask);
6570 ipw_write32(priv, CX2_INTA_RW, inta);
6571
6572 /* Cache INTA value for our tasklet */
6573 priv->isr_inta = inta;
6574
6575 tasklet_schedule(&priv->irq_tasklet);
6576
6577 spin_unlock(&priv->lock);
6578
6579 return IRQ_HANDLED;
6580 none:
6581 spin_unlock(&priv->lock);
6582 return IRQ_NONE;
6583}
6584
6585static void ipw_rf_kill(void *adapter)
6586{
6587 struct ipw_priv *priv = adapter;
6588 unsigned long flags;
6589
6590 spin_lock_irqsave(&priv->lock, flags);
6591
6592 if (rf_kill_active(priv)) {
6593 IPW_DEBUG_RF_KILL("RF Kill active, rescheduling GPIO check\n");
6594 if (priv->workqueue)
6595 queue_delayed_work(priv->workqueue,
6596 &priv->rf_kill, 2 * HZ);
6597 goto exit_unlock;
6598 }
6599
6600 /* RF Kill is now disabled, so bring the device back up */
6601
6602 if (!(priv->status & STATUS_RF_KILL_MASK)) {
6603 IPW_DEBUG_RF_KILL("HW RF Kill no longer active, restarting "
6604 "device\n");
6605
6606 /* we can not do an adapter restart while inside an irq lock */
6607 queue_work(priv->workqueue, &priv->adapter_restart);
6608 } else
6609 IPW_DEBUG_RF_KILL("HW RF Kill deactivated. SW RF Kill still "
6610 "enabled\n");
6611
6612 exit_unlock:
6613 spin_unlock_irqrestore(&priv->lock, flags);
6614}
6615
6616static int ipw_setup_deferred_work(struct ipw_priv *priv)
6617{
6618 int ret = 0;
6619
6620 priv->workqueue = create_workqueue(DRV_NAME);
6621 init_waitqueue_head(&priv->wait_command_queue);
6622
6623 INIT_WORK(&priv->adhoc_check, ipw_adhoc_check, priv);
6624 INIT_WORK(&priv->associate, ipw_associate, priv);
6625 INIT_WORK(&priv->disassociate, ipw_disassociate, priv);
6626 INIT_WORK(&priv->rx_replenish, ipw_rx_queue_replenish, priv);
6627 INIT_WORK(&priv->adapter_restart, ipw_adapter_restart, priv);
6628 INIT_WORK(&priv->rf_kill, ipw_rf_kill, priv);
6629 INIT_WORK(&priv->up, (void (*)(void *))ipw_up, priv);
6630 INIT_WORK(&priv->down, (void (*)(void *))ipw_down, priv);
6631 INIT_WORK(&priv->request_scan,
6632 (void (*)(void *))ipw_request_scan, priv);
6633 INIT_WORK(&priv->gather_stats,
6634 (void (*)(void *))ipw_gather_stats, priv);
6635 INIT_WORK(&priv->abort_scan, (void (*)(void *))ipw_abort_scan, priv);
6636 INIT_WORK(&priv->roam, ipw_roam, priv);
6637 INIT_WORK(&priv->scan_check, ipw_scan_check, priv);
6638
6639 tasklet_init(&priv->irq_tasklet, (void (*)(unsigned long))
6640 ipw_irq_tasklet, (unsigned long)priv);
6641
6642 return ret;
6643}
6644
6645
6646static void shim__set_security(struct net_device *dev,
6647 struct ieee80211_security *sec)
6648{
6649 struct ipw_priv *priv = ieee80211_priv(dev);
6650 int i;
6651
6652 for (i = 0; i < 4; i++) {
6653 if (sec->flags & (1 << i)) {
6654 priv->sec.key_sizes[i] = sec->key_sizes[i];
6655 if (sec->key_sizes[i] == 0)
6656 priv->sec.flags &= ~(1 << i);
6657 else
6658 memcpy(priv->sec.keys[i], sec->keys[i],
6659 sec->key_sizes[i]);
6660 priv->sec.flags |= (1 << i);
6661 priv->status |= STATUS_SECURITY_UPDATED;
6662 }
6663 }
6664
6665 if ((sec->flags & SEC_ACTIVE_KEY) &&
6666 priv->sec.active_key != sec->active_key) {
6667 if (sec->active_key <= 3) {
6668 priv->sec.active_key = sec->active_key;
6669 priv->sec.flags |= SEC_ACTIVE_KEY;
6670 } else
6671 priv->sec.flags &= ~SEC_ACTIVE_KEY;
6672 priv->status |= STATUS_SECURITY_UPDATED;
6673 }
6674
6675 if ((sec->flags & SEC_AUTH_MODE) &&
6676 (priv->sec.auth_mode != sec->auth_mode)) {
6677 priv->sec.auth_mode = sec->auth_mode;
6678 priv->sec.flags |= SEC_AUTH_MODE;
6679 if (sec->auth_mode == WLAN_AUTH_SHARED_KEY)
6680 priv->capability |= CAP_SHARED_KEY;
6681 else
6682 priv->capability &= ~CAP_SHARED_KEY;
6683 priv->status |= STATUS_SECURITY_UPDATED;
6684 }
6685
6686 if (sec->flags & SEC_ENABLED &&
6687 priv->sec.enabled != sec->enabled) {
6688 priv->sec.flags |= SEC_ENABLED;
6689 priv->sec.enabled = sec->enabled;
6690 priv->status |= STATUS_SECURITY_UPDATED;
6691 if (sec->enabled)
6692 priv->capability |= CAP_PRIVACY_ON;
6693 else
6694 priv->capability &= ~CAP_PRIVACY_ON;
6695 }
6696
6697 if (sec->flags & SEC_LEVEL &&
6698 priv->sec.level != sec->level) {
6699 priv->sec.level = sec->level;
6700 priv->sec.flags |= SEC_LEVEL;
6701 priv->status |= STATUS_SECURITY_UPDATED;
6702 }
6703
6704 /* To match current functionality of ipw2100 (which works well w/
6705 * various supplicants, we don't force a disassociate if the
6706 * privacy capability changes ... */
6707#if 0
6708 if ((priv->status & (STATUS_ASSOCIATED | STATUS_ASSOCIATING)) &&
6709 (((priv->assoc_request.capability &
6710 WLAN_CAPABILITY_PRIVACY) && !sec->enabled) ||
6711 (!(priv->assoc_request.capability &
6712 WLAN_CAPABILITY_PRIVACY) && sec->enabled))) {
6713 IPW_DEBUG_ASSOC("Disassociating due to capability "
6714 "change.\n");
6715 ipw_disassociate(priv);
6716 }
6717#endif
6718}
6719
6720static int init_supported_rates(struct ipw_priv *priv,
6721 struct ipw_supported_rates *rates)
6722{
6723 /* TODO: Mask out rates based on priv->rates_mask */
6724
6725 memset(rates, 0, sizeof(*rates));
6726 /* configure supported rates */
6727 switch (priv->ieee->freq_band) {
6728 case IEEE80211_52GHZ_BAND:
6729 rates->ieee_mode = IPW_A_MODE;
6730 rates->purpose = IPW_RATE_CAPABILITIES;
6731 ipw_add_ofdm_scan_rates(rates, IEEE80211_CCK_MODULATION,
6732 IEEE80211_OFDM_DEFAULT_RATES_MASK);
6733 break;
6734
6735 default: /* Mixed or 2.4Ghz */
6736 rates->ieee_mode = IPW_G_MODE;
6737 rates->purpose = IPW_RATE_CAPABILITIES;
6738 ipw_add_cck_scan_rates(rates, IEEE80211_CCK_MODULATION,
6739 IEEE80211_CCK_DEFAULT_RATES_MASK);
6740 if (priv->ieee->modulation & IEEE80211_OFDM_MODULATION) {
6741 ipw_add_ofdm_scan_rates(rates, IEEE80211_CCK_MODULATION,
6742 IEEE80211_OFDM_DEFAULT_RATES_MASK);
6743 }
6744 break;
6745 }
6746
6747 return 0;
6748}
6749
6750static int ipw_config(struct ipw_priv *priv)
6751{
6752 int i;
6753 struct ipw_tx_power tx_power;
6754
6755 memset(&priv->sys_config, 0, sizeof(priv->sys_config));
6756 memset(&tx_power, 0, sizeof(tx_power));
6757
6758 /* This is only called from ipw_up, which resets/reloads the firmware
6759 so, we don't need to first disable the card before we configure
6760 it */
6761
6762 /* configure device for 'G' band */
6763 tx_power.ieee_mode = IPW_G_MODE;
6764 tx_power.num_channels = 11;
6765 for (i = 0; i < 11; i++) {
6766 tx_power.channels_tx_power[i].channel_number = i + 1;
6767 tx_power.channels_tx_power[i].tx_power = priv->tx_power;
6768 }
6769 if (ipw_send_tx_power(priv, &tx_power))
6770 goto error;
6771
6772 /* configure device to also handle 'B' band */
6773 tx_power.ieee_mode = IPW_B_MODE;
6774 if (ipw_send_tx_power(priv, &tx_power))
6775 goto error;
6776
6777 /* initialize adapter address */
6778 if (ipw_send_adapter_address(priv, priv->net_dev->dev_addr))
6779 goto error;
6780
6781 /* set basic system config settings */
6782 init_sys_config(&priv->sys_config);
6783 if (ipw_send_system_config(priv, &priv->sys_config))
6784 goto error;
6785
6786 init_supported_rates(priv, &priv->rates);
6787 if (ipw_send_supported_rates(priv, &priv->rates))
6788 goto error;
6789
6790 /* Set request-to-send threshold */
6791 if (priv->rts_threshold) {
6792 if (ipw_send_rts_threshold(priv, priv->rts_threshold))
6793 goto error;
6794 }
6795
6796 if (ipw_set_random_seed(priv))
6797 goto error;
6798
6799 /* final state transition to the RUN state */
6800 if (ipw_send_host_complete(priv))
6801 goto error;
6802
6803 /* If configured to try and auto-associate, kick off a scan */
6804 if ((priv->config & CFG_ASSOCIATE) && ipw_request_scan(priv))
6805 goto error;
6806
6807 return 0;
6808
6809 error:
6810 return -EIO;
6811}
6812
6813#define MAX_HW_RESTARTS 5
6814static int ipw_up(struct ipw_priv *priv)
6815{
6816 int rc, i;
6817
6818 if (priv->status & STATUS_EXIT_PENDING)
6819 return -EIO;
6820
6821 for (i = 0; i < MAX_HW_RESTARTS; i++ ) {
6822 /* Load the microcode, firmware, and eeprom.
6823 * Also start the clocks. */
6824 rc = ipw_load(priv);
6825 if (rc) {
6826 IPW_ERROR("Unable to load firmware: 0x%08X\n",
6827 rc);
6828 return rc;
6829 }
6830
6831 ipw_init_ordinals(priv);
6832 if (!(priv->config & CFG_CUSTOM_MAC))
6833 eeprom_parse_mac(priv, priv->mac_addr);
6834 memcpy(priv->net_dev->dev_addr, priv->mac_addr, ETH_ALEN);
6835
6836 if (priv->status & STATUS_RF_KILL_MASK)
6837 return 0;
6838
6839 rc = ipw_config(priv);
6840 if (!rc) {
6841 IPW_DEBUG_INFO("Configured device on count %i\n", i);
6842 priv->notif_missed_beacons = 0;
6843 netif_start_queue(priv->net_dev);
6844 return 0;
6845 } else {
6846 IPW_DEBUG_INFO("Device configuration failed: 0x%08X\n",
6847 rc);
6848 }
6849
6850 IPW_DEBUG_INFO("Failed to config device on retry %d of %d\n",
6851 i, MAX_HW_RESTARTS);
6852
6853 /* We had an error bringing up the hardware, so take it
6854 * all the way back down so we can try again */
6855 ipw_down(priv);
6856 }
6857
6858 /* tried to restart and config the device for as long as our
6859 * patience could withstand */
6860 IPW_ERROR("Unable to initialize device after %d attempts.\n",
6861 i);
6862 return -EIO;
6863}
6864
6865static void ipw_down(struct ipw_priv *priv)
6866{
6867 /* Attempt to disable the card */
6868#if 0
6869 ipw_send_card_disable(priv, 0);
6870#endif
6871
6872 /* tell the device to stop sending interrupts */
6873 ipw_disable_interrupts(priv);
6874
6875 /* Clear all bits but the RF Kill */
6876 priv->status &= STATUS_RF_KILL_MASK;
6877
6878 netif_carrier_off(priv->net_dev);
6879 netif_stop_queue(priv->net_dev);
6880
6881 ipw_stop_nic(priv);
6882}
6883
6884/* Called by register_netdev() */
6885static int ipw_net_init(struct net_device *dev)
6886{
6887 struct ipw_priv *priv = ieee80211_priv(dev);
6888
6889 if (priv->status & STATUS_RF_KILL_SW) {
6890 IPW_WARNING("Radio disabled by module parameter.\n");
6891 return 0;
6892 } else if (rf_kill_active(priv)) {
6893 IPW_WARNING("Radio Frequency Kill Switch is On:\n"
6894 "Kill switch must be turned off for "
6895 "wireless networking to work.\n");
6896 queue_delayed_work(priv->workqueue, &priv->rf_kill, 2 * HZ);
6897 return 0;
6898 }
6899
6900 if (ipw_up(priv))
6901 return -EIO;
6902
6903 return 0;
6904}
6905
6906/* PCI driver stuff */
6907static struct pci_device_id card_ids[] = {
6908 {PCI_VENDOR_ID_INTEL, 0x1043, 0x8086, 0x2701, 0, 0, 0},
6909 {PCI_VENDOR_ID_INTEL, 0x1043, 0x8086, 0x2702, 0, 0, 0},
6910 {PCI_VENDOR_ID_INTEL, 0x1043, 0x8086, 0x2711, 0, 0, 0},
6911 {PCI_VENDOR_ID_INTEL, 0x1043, 0x8086, 0x2712, 0, 0, 0},
6912 {PCI_VENDOR_ID_INTEL, 0x1043, 0x8086, 0x2721, 0, 0, 0},
6913 {PCI_VENDOR_ID_INTEL, 0x1043, 0x8086, 0x2722, 0, 0, 0},
6914 {PCI_VENDOR_ID_INTEL, 0x1043, 0x8086, 0x2731, 0, 0, 0},
6915 {PCI_VENDOR_ID_INTEL, 0x1043, 0x8086, 0x2732, 0, 0, 0},
6916 {PCI_VENDOR_ID_INTEL, 0x1043, 0x8086, 0x2741, 0, 0, 0},
6917 {PCI_VENDOR_ID_INTEL, 0x1043, 0x103c, 0x2741, 0, 0, 0},
6918 {PCI_VENDOR_ID_INTEL, 0x1043, 0x8086, 0x2742, 0, 0, 0},
6919 {PCI_VENDOR_ID_INTEL, 0x1043, 0x8086, 0x2751, 0, 0, 0},
6920 {PCI_VENDOR_ID_INTEL, 0x1043, 0x8086, 0x2752, 0, 0, 0},
6921 {PCI_VENDOR_ID_INTEL, 0x1043, 0x8086, 0x2753, 0, 0, 0},
6922 {PCI_VENDOR_ID_INTEL, 0x1043, 0x8086, 0x2754, 0, 0, 0},
6923 {PCI_VENDOR_ID_INTEL, 0x1043, 0x8086, 0x2761, 0, 0, 0},
6924 {PCI_VENDOR_ID_INTEL, 0x1043, 0x8086, 0x2762, 0, 0, 0},
6925 {PCI_VENDOR_ID_INTEL, 0x104f, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
6926 {PCI_VENDOR_ID_INTEL, 0x4220, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, /* BG */
6927 {PCI_VENDOR_ID_INTEL, 0x4221, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, /* 2225BG */
6928 {PCI_VENDOR_ID_INTEL, 0x4223, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, /* ABG */
6929 {PCI_VENDOR_ID_INTEL, 0x4224, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, /* ABG */
6930
6931 /* required last entry */
6932 {0,}
6933};
6934
6935MODULE_DEVICE_TABLE(pci, card_ids);
6936
6937static struct attribute *ipw_sysfs_entries[] = {
6938 &dev_attr_rf_kill.attr,
6939 &dev_attr_direct_dword.attr,
6940 &dev_attr_indirect_byte.attr,
6941 &dev_attr_indirect_dword.attr,
6942 &dev_attr_mem_gpio_reg.attr,
6943 &dev_attr_command_event_reg.attr,
6944 &dev_attr_nic_type.attr,
6945 &dev_attr_status.attr,
6946 &dev_attr_cfg.attr,
6947 &dev_attr_dump_errors.attr,
6948 &dev_attr_dump_events.attr,
6949 &dev_attr_eeprom_delay.attr,
6950 &dev_attr_ucode_version.attr,
6951 &dev_attr_rtc.attr,
6952 NULL
6953};
6954
6955static struct attribute_group ipw_attribute_group = {
6956 .name = NULL, /* put in device directory */
6957 .attrs = ipw_sysfs_entries,
6958};
6959
6960static int ipw_pci_probe(struct pci_dev *pdev,
6961 const struct pci_device_id *ent)
6962{
6963 int err = 0;
6964 struct net_device *net_dev;
6965 void __iomem *base;
6966 u32 length, val;
6967 struct ipw_priv *priv;
6968 int band, modulation;
6969
6970 net_dev = alloc_ieee80211(sizeof(struct ipw_priv));
6971 if (net_dev == NULL) {
6972 err = -ENOMEM;
6973 goto out;
6974 }
6975
6976 priv = ieee80211_priv(net_dev);
6977 priv->ieee = netdev_priv(net_dev);
6978 priv->net_dev = net_dev;
6979 priv->pci_dev = pdev;
6980#ifdef CONFIG_IPW_DEBUG
6981 ipw_debug_level = debug;
6982#endif
6983 spin_lock_init(&priv->lock);
6984
6985 if (pci_enable_device(pdev)) {
6986 err = -ENODEV;
6987 goto out_free_ieee80211;
6988 }
6989
6990 pci_set_master(pdev);
6991
6992 err = pci_set_dma_mask(pdev, DMA_32BIT_MASK);
6993 if (!err)
6994 err = pci_set_consistent_dma_mask(pdev, DMA_32BIT_MASK);
6995 if (err) {
6996 printk(KERN_WARNING DRV_NAME ": No suitable DMA available.\n");
6997 goto out_pci_disable_device;
6998 }
6999
7000 pci_set_drvdata(pdev, priv);
7001
7002 err = pci_request_regions(pdev, DRV_NAME);
7003 if (err)
7004 goto out_pci_disable_device;
7005
7006 /* We disable the RETRY_TIMEOUT register (0x41) to keep
7007 * PCI Tx retries from interfering with C3 CPU state */
7008 pci_read_config_dword(pdev, 0x40, &val);
7009 if ((val & 0x0000ff00) != 0)
7010 pci_write_config_dword(pdev, 0x40, val & 0xffff00ff);
7011
7012 length = pci_resource_len(pdev, 0);
7013 priv->hw_len = length;
7014
7015 base = ioremap_nocache(pci_resource_start(pdev, 0), length);
7016 if (!base) {
7017 err = -ENODEV;
7018 goto out_pci_release_regions;
7019 }
7020
7021 priv->hw_base = base;
7022 IPW_DEBUG_INFO("pci_resource_len = 0x%08x\n", length);
7023 IPW_DEBUG_INFO("pci_resource_base = %p\n", base);
7024
7025 err = ipw_setup_deferred_work(priv);
7026 if (err) {
7027 IPW_ERROR("Unable to setup deferred work\n");
7028 goto out_iounmap;
7029 }
7030
7031 /* Initialize module parameter values here */
7032 if (ifname)
7033 strncpy(net_dev->name, ifname, IFNAMSIZ);
7034
7035 if (associate)
7036 priv->config |= CFG_ASSOCIATE;
7037 else
7038 IPW_DEBUG_INFO("Auto associate disabled.\n");
7039
7040 if (auto_create)
7041 priv->config |= CFG_ADHOC_CREATE;
7042 else
7043 IPW_DEBUG_INFO("Auto adhoc creation disabled.\n");
7044
7045 if (disable) {
7046 priv->status |= STATUS_RF_KILL_SW;
7047 IPW_DEBUG_INFO("Radio disabled.\n");
7048 }
7049
7050 if (channel != 0) {
7051 priv->config |= CFG_STATIC_CHANNEL;
7052 priv->channel = channel;
7053 IPW_DEBUG_INFO("Bind to static channel %d\n", channel);
7054 IPW_DEBUG_INFO("Bind to static channel %d\n", channel);
7055 /* TODO: Validate that provided channel is in range */
7056 }
7057
7058 switch (mode) {
7059 case 1:
7060 priv->ieee->iw_mode = IW_MODE_ADHOC;
7061 break;
7062#ifdef CONFIG_IPW_PROMISC
7063 case 2:
7064 priv->ieee->iw_mode = IW_MODE_MONITOR;
7065 break;
7066#endif
7067 default:
7068 case 0:
7069 priv->ieee->iw_mode = IW_MODE_INFRA;
7070 break;
7071 }
7072
7073 if ((priv->pci_dev->device == 0x4223) ||
7074 (priv->pci_dev->device == 0x4224)) {
7075 printk(KERN_INFO DRV_NAME
7076 ": Detected Intel PRO/Wireless 2915ABG Network "
7077 "Connection\n");
7078 priv->ieee->abg_ture = 1;
7079 band = IEEE80211_52GHZ_BAND | IEEE80211_24GHZ_BAND;
7080 modulation = IEEE80211_OFDM_MODULATION |
7081 IEEE80211_CCK_MODULATION;
7082 priv->adapter = IPW_2915ABG;
7083 priv->ieee->mode = IEEE_A|IEEE_G|IEEE_B;
7084 } else {
7085 if (priv->pci_dev->device == 0x4221)
7086 printk(KERN_INFO DRV_NAME
7087 ": Detected Intel PRO/Wireless 2225BG Network "
7088 "Connection\n");
7089 else
7090 printk(KERN_INFO DRV_NAME
7091 ": Detected Intel PRO/Wireless 2200BG Network "
7092 "Connection\n");
7093
7094 priv->ieee->abg_ture = 0;
7095 band = IEEE80211_24GHZ_BAND;
7096 modulation = IEEE80211_OFDM_MODULATION |
7097 IEEE80211_CCK_MODULATION;
7098 priv->adapter = IPW_2200BG;
7099 priv->ieee->mode = IEEE_G|IEEE_B;
7100 }
7101
7102 priv->ieee->freq_band = band;
7103 priv->ieee->modulation = modulation;
7104
7105 priv->rates_mask = IEEE80211_DEFAULT_RATES_MASK;
7106
7107 priv->missed_beacon_threshold = IPW_MB_DISASSOCIATE_THRESHOLD_DEFAULT;
7108 priv->roaming_threshold = IPW_MB_ROAMING_THRESHOLD_DEFAULT;
7109
7110 priv->rts_threshold = DEFAULT_RTS_THRESHOLD;
7111
7112 /* If power management is turned on, default to AC mode */
7113 priv->power_mode = IPW_POWER_AC;
7114 priv->tx_power = IPW_DEFAULT_TX_POWER;
7115
7116 err = request_irq(pdev->irq, ipw_isr, SA_SHIRQ, DRV_NAME,
7117 priv);
7118 if (err) {
7119 IPW_ERROR("Error allocating IRQ %d\n", pdev->irq);
7120 goto out_destroy_workqueue;
7121 }
7122
7123 SET_MODULE_OWNER(net_dev);
7124 SET_NETDEV_DEV(net_dev, &pdev->dev);
7125
7126 priv->ieee->hard_start_xmit = ipw_net_hard_start_xmit;
7127 priv->ieee->set_security = shim__set_security;
7128
7129 net_dev->open = ipw_net_open;
7130 net_dev->stop = ipw_net_stop;
7131 net_dev->init = ipw_net_init;
7132 net_dev->get_stats = ipw_net_get_stats;
7133 net_dev->set_multicast_list = ipw_net_set_multicast_list;
7134 net_dev->set_mac_address = ipw_net_set_mac_address;
7135 net_dev->get_wireless_stats = ipw_get_wireless_stats;
7136 net_dev->wireless_handlers = &ipw_wx_handler_def;
7137 net_dev->ethtool_ops = &ipw_ethtool_ops;
7138 net_dev->irq = pdev->irq;
7139 net_dev->base_addr = (unsigned long )priv->hw_base;
7140 net_dev->mem_start = pci_resource_start(pdev, 0);
7141 net_dev->mem_end = net_dev->mem_start + pci_resource_len(pdev, 0) - 1;
7142
7143 err = sysfs_create_group(&pdev->dev.kobj, &ipw_attribute_group);
7144 if (err) {
7145 IPW_ERROR("failed to create sysfs device attributes\n");
7146 goto out_release_irq;
7147 }
7148
7149 err = register_netdev(net_dev);
7150 if (err) {
7151 IPW_ERROR("failed to register network device\n");
7152 goto out_remove_group;
7153 }
7154
7155 return 0;
7156
7157 out_remove_group:
7158 sysfs_remove_group(&pdev->dev.kobj, &ipw_attribute_group);
7159 out_release_irq:
7160 free_irq(pdev->irq, priv);
7161 out_destroy_workqueue:
7162 destroy_workqueue(priv->workqueue);
7163 priv->workqueue = NULL;
7164 out_iounmap:
7165 iounmap(priv->hw_base);
7166 out_pci_release_regions:
7167 pci_release_regions(pdev);
7168 out_pci_disable_device:
7169 pci_disable_device(pdev);
7170 pci_set_drvdata(pdev, NULL);
7171 out_free_ieee80211:
7172 free_ieee80211(priv->net_dev);
7173 out:
7174 return err;
7175}
7176
7177static void ipw_pci_remove(struct pci_dev *pdev)
7178{
7179 struct ipw_priv *priv = pci_get_drvdata(pdev);
7180 if (!priv)
7181 return;
7182
7183 priv->status |= STATUS_EXIT_PENDING;
7184
7185 sysfs_remove_group(&pdev->dev.kobj, &ipw_attribute_group);
7186
7187 ipw_down(priv);
7188
7189 unregister_netdev(priv->net_dev);
7190
7191 if (priv->rxq) {
7192 ipw_rx_queue_free(priv, priv->rxq);
7193 priv->rxq = NULL;
7194 }
7195 ipw_tx_queue_free(priv);
7196
7197 /* ipw_down will ensure that there is no more pending work
7198 * in the workqueue's, so we can safely remove them now. */
7199 if (priv->workqueue) {
7200 cancel_delayed_work(&priv->adhoc_check);
7201 cancel_delayed_work(&priv->gather_stats);
7202 cancel_delayed_work(&priv->request_scan);
7203 cancel_delayed_work(&priv->rf_kill);
7204 cancel_delayed_work(&priv->scan_check);
7205 destroy_workqueue(priv->workqueue);
7206 priv->workqueue = NULL;
7207 }
7208
7209 free_irq(pdev->irq, priv);
7210 iounmap(priv->hw_base);
7211 pci_release_regions(pdev);
7212 pci_disable_device(pdev);
7213 pci_set_drvdata(pdev, NULL);
7214 free_ieee80211(priv->net_dev);
7215
7216#ifdef CONFIG_PM
7217 if (fw_loaded) {
7218 release_firmware(bootfw);
7219 release_firmware(ucode);
7220 release_firmware(firmware);
7221 fw_loaded = 0;
7222 }
7223#endif
7224}
7225
7226
7227#ifdef CONFIG_PM
7228static int ipw_pci_suspend(struct pci_dev *pdev, u32 state)
7229{
7230 struct ipw_priv *priv = pci_get_drvdata(pdev);
7231 struct net_device *dev = priv->net_dev;
7232
7233 printk(KERN_INFO "%s: Going into suspend...\n", dev->name);
7234
7235 /* Take down the device; powers it off, etc. */
7236 ipw_down(priv);
7237
7238 /* Remove the PRESENT state of the device */
7239 netif_device_detach(dev);
7240
7241 pci_save_state(pdev);
7242 pci_disable_device(pdev);
7243 pci_set_power_state(pdev, state);
7244
7245 return 0;
7246}
7247
7248static int ipw_pci_resume(struct pci_dev *pdev)
7249{
7250 struct ipw_priv *priv = pci_get_drvdata(pdev);
7251 struct net_device *dev = priv->net_dev;
7252 u32 val;
7253
7254 printk(KERN_INFO "%s: Coming out of suspend...\n", dev->name);
7255
7256 pci_set_power_state(pdev, 0);
7257 pci_enable_device(pdev);
7258#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,10)
7259 pci_restore_state(pdev, priv->pm_state);
7260#else
7261 pci_restore_state(pdev);
7262#endif
7263 /*
7264 * Suspend/Resume resets the PCI configuration space, so we have to
7265 * re-disable the RETRY_TIMEOUT register (0x41) to keep PCI Tx retries
7266 * from interfering with C3 CPU state. pci_restore_state won't help
7267 * here since it only restores the first 64 bytes pci config header.
7268 */
7269 pci_read_config_dword(pdev, 0x40, &val);
7270 if ((val & 0x0000ff00) != 0)
7271 pci_write_config_dword(pdev, 0x40, val & 0xffff00ff);
7272
7273 /* Set the device back into the PRESENT state; this will also wake
7274 * the queue of needed */
7275 netif_device_attach(dev);
7276
7277 /* Bring the device back up */
7278 queue_work(priv->workqueue, &priv->up);
7279
7280 return 0;
7281}
7282#endif
7283
7284/* driver initialization stuff */
7285static struct pci_driver ipw_driver = {
7286 .name = DRV_NAME,
7287 .id_table = card_ids,
7288 .probe = ipw_pci_probe,
7289 .remove = __devexit_p(ipw_pci_remove),
7290#ifdef CONFIG_PM
7291 .suspend = ipw_pci_suspend,
7292 .resume = ipw_pci_resume,
7293#endif
7294};
7295
7296static int __init ipw_init(void)
7297{
7298 int ret;
7299
7300 printk(KERN_INFO DRV_NAME ": " DRV_DESCRIPTION ", " DRV_VERSION "\n");
7301 printk(KERN_INFO DRV_NAME ": " DRV_COPYRIGHT "\n");
7302
7303 ret = pci_module_init(&ipw_driver);
7304 if (ret) {
7305 IPW_ERROR("Unable to initialize PCI module\n");
7306 return ret;
7307 }
7308
7309 ret = driver_create_file(&ipw_driver.driver,
7310 &driver_attr_debug_level);
7311 if (ret) {
7312 IPW_ERROR("Unable to create driver sysfs file\n");
7313 pci_unregister_driver(&ipw_driver);
7314 return ret;
7315 }
7316
7317 return ret;
7318}
7319
7320static void __exit ipw_exit(void)
7321{
7322 driver_remove_file(&ipw_driver.driver, &driver_attr_debug_level);
7323 pci_unregister_driver(&ipw_driver);
7324}
7325
7326module_param(disable, int, 0444);
7327MODULE_PARM_DESC(disable, "manually disable the radio (default 0 [radio on])");
7328
7329module_param(associate, int, 0444);
7330MODULE_PARM_DESC(associate, "auto associate when scanning (default on)");
7331
7332module_param(auto_create, int, 0444);
7333MODULE_PARM_DESC(auto_create, "auto create adhoc network (default on)");
7334
7335module_param(debug, int, 0444);
7336MODULE_PARM_DESC(debug, "debug output mask");
7337
7338module_param(channel, int, 0444);
7339MODULE_PARM_DESC(channel, "channel to limit associate to (default 0 [ANY])");
7340
7341module_param(ifname, charp, 0444);
7342MODULE_PARM_DESC(ifname, "network device name (default eth%d)");
7343
7344#ifdef CONFIG_IPW_PROMISC
7345module_param(mode, int, 0444);
7346MODULE_PARM_DESC(mode, "network mode (0=BSS,1=IBSS,2=Monitor)");
7347#else
7348module_param(mode, int, 0444);
7349MODULE_PARM_DESC(mode, "network mode (0=BSS,1=IBSS)");
7350#endif
7351
7352module_exit(ipw_exit);
7353module_init(ipw_init);
diff --git a/drivers/net/wireless/ipw2200.h b/drivers/net/wireless/ipw2200.h
new file mode 100644
index 000000000000..3bff09d93154
--- /dev/null
+++ b/drivers/net/wireless/ipw2200.h
@@ -0,0 +1,1742 @@
1/******************************************************************************
2
3 Copyright(c) 2003 - 2004 Intel Corporation. All rights reserved.
4
5 This program is free software; you can redistribute it and/or modify it
6 under the terms of version 2 of the GNU General Public License as
7 published by the Free Software Foundation.
8
9 This program is distributed in the hope that it will be useful, but WITHOUT
10 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11 FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
12 more details.
13
14 You should have received a copy of the GNU General Public License along with
15 this program; if not, write to the Free Software Foundation, Inc., 59
16 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
17
18 The full GNU General Public License is included in this distribution in the
19 file called LICENSE.
20
21 Contact Information:
22 James P. Ketrenos <ipw2100-admin@linux.intel.com>
23 Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497
24
25******************************************************************************/
26
27#ifndef __ipw2200_h__
28#define __ipw2200_h__
29
30#define WEXT_USECHANNELS 1
31
32#include <linux/module.h>
33#include <linux/moduleparam.h>
34#include <linux/config.h>
35#include <linux/init.h>
36
37#include <linux/version.h>
38#include <linux/pci.h>
39#include <linux/netdevice.h>
40#include <linux/ethtool.h>
41#include <linux/skbuff.h>
42#include <linux/etherdevice.h>
43#include <linux/delay.h>
44#include <linux/random.h>
45
46#include <linux/firmware.h>
47#include <linux/wireless.h>
48#include <asm/io.h>
49
50#include <net/ieee80211.h>
51
52#define DRV_NAME "ipw2200"
53
54#include <linux/workqueue.h>
55
56/* Authentication and Association States */
57enum connection_manager_assoc_states
58{
59 CMAS_INIT = 0,
60 CMAS_TX_AUTH_SEQ_1,
61 CMAS_RX_AUTH_SEQ_2,
62 CMAS_AUTH_SEQ_1_PASS,
63 CMAS_AUTH_SEQ_1_FAIL,
64 CMAS_TX_AUTH_SEQ_3,
65 CMAS_RX_AUTH_SEQ_4,
66 CMAS_AUTH_SEQ_2_PASS,
67 CMAS_AUTH_SEQ_2_FAIL,
68 CMAS_AUTHENTICATED,
69 CMAS_TX_ASSOC,
70 CMAS_RX_ASSOC_RESP,
71 CMAS_ASSOCIATED,
72 CMAS_LAST
73};
74
75
76#define IPW_WAIT (1<<0)
77#define IPW_QUIET (1<<1)
78#define IPW_ROAMING (1<<2)
79
80#define IPW_POWER_MODE_CAM 0x00 //(always on)
81#define IPW_POWER_INDEX_1 0x01
82#define IPW_POWER_INDEX_2 0x02
83#define IPW_POWER_INDEX_3 0x03
84#define IPW_POWER_INDEX_4 0x04
85#define IPW_POWER_INDEX_5 0x05
86#define IPW_POWER_AC 0x06
87#define IPW_POWER_BATTERY 0x07
88#define IPW_POWER_LIMIT 0x07
89#define IPW_POWER_MASK 0x0F
90#define IPW_POWER_ENABLED 0x10
91#define IPW_POWER_LEVEL(x) ((x) & IPW_POWER_MASK)
92
93#define IPW_CMD_HOST_COMPLETE 2
94#define IPW_CMD_POWER_DOWN 4
95#define IPW_CMD_SYSTEM_CONFIG 6
96#define IPW_CMD_MULTICAST_ADDRESS 7
97#define IPW_CMD_SSID 8
98#define IPW_CMD_ADAPTER_ADDRESS 11
99#define IPW_CMD_PORT_TYPE 12
100#define IPW_CMD_RTS_THRESHOLD 15
101#define IPW_CMD_FRAG_THRESHOLD 16
102#define IPW_CMD_POWER_MODE 17
103#define IPW_CMD_WEP_KEY 18
104#define IPW_CMD_TGI_TX_KEY 19
105#define IPW_CMD_SCAN_REQUEST 20
106#define IPW_CMD_ASSOCIATE 21
107#define IPW_CMD_SUPPORTED_RATES 22
108#define IPW_CMD_SCAN_ABORT 23
109#define IPW_CMD_TX_FLUSH 24
110#define IPW_CMD_QOS_PARAMETERS 25
111#define IPW_CMD_SCAN_REQUEST_EXT 26
112#define IPW_CMD_DINO_CONFIG 30
113#define IPW_CMD_RSN_CAPABILITIES 31
114#define IPW_CMD_RX_KEY 32
115#define IPW_CMD_CARD_DISABLE 33
116#define IPW_CMD_SEED_NUMBER 34
117#define IPW_CMD_TX_POWER 35
118#define IPW_CMD_COUNTRY_INFO 36
119#define IPW_CMD_AIRONET_INFO 37
120#define IPW_CMD_AP_TX_POWER 38
121#define IPW_CMD_CCKM_INFO 39
122#define IPW_CMD_CCX_VER_INFO 40
123#define IPW_CMD_SET_CALIBRATION 41
124#define IPW_CMD_SENSITIVITY_CALIB 42
125#define IPW_CMD_RETRY_LIMIT 51
126#define IPW_CMD_IPW_PRE_POWER_DOWN 58
127#define IPW_CMD_VAP_BEACON_TEMPLATE 60
128#define IPW_CMD_VAP_DTIM_PERIOD 61
129#define IPW_CMD_EXT_SUPPORTED_RATES 62
130#define IPW_CMD_VAP_LOCAL_TX_PWR_CONSTRAINT 63
131#define IPW_CMD_VAP_QUIET_INTERVALS 64
132#define IPW_CMD_VAP_CHANNEL_SWITCH 65
133#define IPW_CMD_VAP_MANDATORY_CHANNELS 66
134#define IPW_CMD_VAP_CELL_PWR_LIMIT 67
135#define IPW_CMD_VAP_CF_PARAM_SET 68
136#define IPW_CMD_VAP_SET_BEACONING_STATE 69
137#define IPW_CMD_MEASUREMENT 80
138#define IPW_CMD_POWER_CAPABILITY 81
139#define IPW_CMD_SUPPORTED_CHANNELS 82
140#define IPW_CMD_TPC_REPORT 83
141#define IPW_CMD_WME_INFO 84
142#define IPW_CMD_PRODUCTION_COMMAND 85
143#define IPW_CMD_LINKSYS_EOU_INFO 90
144
145#define RFD_SIZE 4
146#define NUM_TFD_CHUNKS 6
147
148#define TX_QUEUE_SIZE 32
149#define RX_QUEUE_SIZE 32
150
151#define DINO_CMD_WEP_KEY 0x08
152#define DINO_CMD_TX 0x0B
153#define DCT_ANTENNA_A 0x01
154#define DCT_ANTENNA_B 0x02
155
156#define IPW_A_MODE 0
157#define IPW_B_MODE 1
158#define IPW_G_MODE 2
159
160/*
161 * TX Queue Flag Definitions
162 */
163
164/* abort attempt if mgmt frame is rx'd */
165#define DCT_FLAG_ABORT_MGMT 0x01
166
167/* require CTS */
168#define DCT_FLAG_CTS_REQUIRED 0x02
169
170/* use short preamble */
171#define DCT_FLAG_SHORT_PREMBL 0x04
172
173/* RTS/CTS first */
174#define DCT_FLAG_RTS_REQD 0x08
175
176/* dont calculate duration field */
177#define DCT_FLAG_DUR_SET 0x10
178
179/* even if MAC WEP set (allows pre-encrypt) */
180#define DCT_FLAG_NO_WEP 0x20
181
182/* overwrite TSF field */
183#define DCT_FLAG_TSF_REQD 0x40
184
185/* ACK rx is expected to follow */
186#define DCT_FLAG_ACK_REQD 0x80
187
188#define DCT_FLAG_EXT_MODE_CCK 0x01
189#define DCT_FLAG_EXT_MODE_OFDM 0x00
190
191
192#define TX_RX_TYPE_MASK 0xFF
193#define TX_FRAME_TYPE 0x00
194#define TX_HOST_COMMAND_TYPE 0x01
195#define RX_FRAME_TYPE 0x09
196#define RX_HOST_NOTIFICATION_TYPE 0x03
197#define RX_HOST_CMD_RESPONSE_TYPE 0x04
198#define RX_TX_FRAME_RESPONSE_TYPE 0x05
199#define TFD_NEED_IRQ_MASK 0x04
200
201#define HOST_CMD_DINO_CONFIG 30
202
203#define HOST_NOTIFICATION_STATUS_ASSOCIATED 10
204#define HOST_NOTIFICATION_STATUS_AUTHENTICATE 11
205#define HOST_NOTIFICATION_STATUS_SCAN_CHANNEL_RESULT 12
206#define HOST_NOTIFICATION_STATUS_SCAN_COMPLETED 13
207#define HOST_NOTIFICATION_STATUS_FRAG_LENGTH 14
208#define HOST_NOTIFICATION_STATUS_LINK_DETERIORATION 15
209#define HOST_NOTIFICATION_DINO_CONFIG_RESPONSE 16
210#define HOST_NOTIFICATION_STATUS_BEACON_STATE 17
211#define HOST_NOTIFICATION_STATUS_TGI_TX_KEY 18
212#define HOST_NOTIFICATION_TX_STATUS 19
213#define HOST_NOTIFICATION_CALIB_KEEP_RESULTS 20
214#define HOST_NOTIFICATION_MEASUREMENT_STARTED 21
215#define HOST_NOTIFICATION_MEASUREMENT_ENDED 22
216#define HOST_NOTIFICATION_CHANNEL_SWITCHED 23
217#define HOST_NOTIFICATION_RX_DURING_QUIET_PERIOD 24
218#define HOST_NOTIFICATION_NOISE_STATS 25
219#define HOST_NOTIFICATION_S36_MEASUREMENT_ACCEPTED 30
220#define HOST_NOTIFICATION_S36_MEASUREMENT_REFUSED 31
221
222#define HOST_NOTIFICATION_STATUS_BEACON_MISSING 1
223#define IPW_MB_DISASSOCIATE_THRESHOLD_DEFAULT 24
224#define IPW_MB_ROAMING_THRESHOLD_DEFAULT 8
225#define IPW_REAL_RATE_RX_PACKET_THRESHOLD 300
226
227#define MACADRR_BYTE_LEN 6
228
229#define DCR_TYPE_AP 0x01
230#define DCR_TYPE_WLAP 0x02
231#define DCR_TYPE_MU_ESS 0x03
232#define DCR_TYPE_MU_IBSS 0x04
233#define DCR_TYPE_MU_PIBSS 0x05
234#define DCR_TYPE_SNIFFER 0x06
235#define DCR_TYPE_MU_BSS DCR_TYPE_MU_ESS
236
237/**
238 * Generic queue structure
239 *
240 * Contains common data for Rx and Tx queues
241 */
242struct clx2_queue {
243 int n_bd; /**< number of BDs in this queue */
244 int first_empty; /**< 1-st empty entry (index) */
245 int last_used; /**< last used entry (index) */
246 u32 reg_w; /**< 'write' reg (queue head), addr in domain 1 */
247 u32 reg_r; /**< 'read' reg (queue tail), addr in domain 1 */
248 dma_addr_t dma_addr; /**< physical addr for BD's */
249 int low_mark; /**< low watermark, resume queue if free space more than this */
250 int high_mark; /**< high watermark, stop queue if free space less than this */
251} __attribute__ ((packed));
252
253struct machdr32
254{
255 u16 frame_ctl;
256 u16 duration; // watch out for endians!
257 u8 addr1[ MACADRR_BYTE_LEN ];
258 u8 addr2[ MACADRR_BYTE_LEN ];
259 u8 addr3[ MACADRR_BYTE_LEN ];
260 u16 seq_ctrl; // more endians!
261 u8 addr4[ MACADRR_BYTE_LEN ];
262 u16 qos_ctrl;
263} __attribute__ ((packed)) ;
264
265struct machdr30
266{
267 u16 frame_ctl;
268 u16 duration; // watch out for endians!
269 u8 addr1[ MACADRR_BYTE_LEN ];
270 u8 addr2[ MACADRR_BYTE_LEN ];
271 u8 addr3[ MACADRR_BYTE_LEN ];
272 u16 seq_ctrl; // more endians!
273 u8 addr4[ MACADRR_BYTE_LEN ];
274} __attribute__ ((packed)) ;
275
276struct machdr26
277{
278 u16 frame_ctl;
279 u16 duration; // watch out for endians!
280 u8 addr1[ MACADRR_BYTE_LEN ];
281 u8 addr2[ MACADRR_BYTE_LEN ];
282 u8 addr3[ MACADRR_BYTE_LEN ];
283 u16 seq_ctrl; // more endians!
284 u16 qos_ctrl;
285} __attribute__ ((packed)) ;
286
287struct machdr24
288{
289 u16 frame_ctl;
290 u16 duration; // watch out for endians!
291 u8 addr1[ MACADRR_BYTE_LEN ];
292 u8 addr2[ MACADRR_BYTE_LEN ];
293 u8 addr3[ MACADRR_BYTE_LEN ];
294 u16 seq_ctrl; // more endians!
295} __attribute__ ((packed)) ;
296
297// TX TFD with 32 byte MAC Header
298struct tx_tfd_32
299{
300 struct machdr32 mchdr; // 32
301 u32 uivplaceholder[2]; // 8
302} __attribute__ ((packed)) ;
303
304// TX TFD with 30 byte MAC Header
305struct tx_tfd_30
306{
307 struct machdr30 mchdr; // 30
308 u8 reserved[2]; // 2
309 u32 uivplaceholder[2]; // 8
310} __attribute__ ((packed)) ;
311
312// tx tfd with 26 byte mac header
313struct tx_tfd_26
314{
315 struct machdr26 mchdr; // 26
316 u8 reserved1[2]; // 2
317 u32 uivplaceholder[2]; // 8
318 u8 reserved2[4]; // 4
319} __attribute__ ((packed)) ;
320
321// tx tfd with 24 byte mac header
322struct tx_tfd_24
323{
324 struct machdr24 mchdr; // 24
325 u32 uivplaceholder[2]; // 8
326 u8 reserved[8]; // 8
327} __attribute__ ((packed)) ;
328
329
330#define DCT_WEP_KEY_FIELD_LENGTH 16
331
332struct tfd_command
333{
334 u8 index;
335 u8 length;
336 u16 reserved;
337 u8 payload[0];
338} __attribute__ ((packed)) ;
339
340struct tfd_data {
341 /* Header */
342 u32 work_area_ptr;
343 u8 station_number; /* 0 for BSS */
344 u8 reserved1;
345 u16 reserved2;
346
347 /* Tx Parameters */
348 u8 cmd_id;
349 u8 seq_num;
350 u16 len;
351 u8 priority;
352 u8 tx_flags;
353 u8 tx_flags_ext;
354 u8 key_index;
355 u8 wepkey[DCT_WEP_KEY_FIELD_LENGTH];
356 u8 rate;
357 u8 antenna;
358 u16 next_packet_duration;
359 u16 next_frag_len;
360 u16 back_off_counter; //////txop;
361 u8 retrylimit;
362 u16 cwcurrent;
363 u8 reserved3;
364
365 /* 802.11 MAC Header */
366 union
367 {
368 struct tx_tfd_24 tfd_24;
369 struct tx_tfd_26 tfd_26;
370 struct tx_tfd_30 tfd_30;
371 struct tx_tfd_32 tfd_32;
372 } tfd;
373
374 /* Payload DMA info */
375 u32 num_chunks;
376 u32 chunk_ptr[NUM_TFD_CHUNKS];
377 u16 chunk_len[NUM_TFD_CHUNKS];
378} __attribute__ ((packed));
379
380struct txrx_control_flags
381{
382 u8 message_type;
383 u8 rx_seq_num;
384 u8 control_bits;
385 u8 reserved;
386} __attribute__ ((packed));
387
388#define TFD_SIZE 128
389#define TFD_CMD_IMMEDIATE_PAYLOAD_LENGTH (TFD_SIZE - sizeof(struct txrx_control_flags))
390
391struct tfd_frame
392{
393 struct txrx_control_flags control_flags;
394 union {
395 struct tfd_data data;
396 struct tfd_command cmd;
397 u8 raw[TFD_CMD_IMMEDIATE_PAYLOAD_LENGTH];
398 } u;
399} __attribute__ ((packed)) ;
400
401typedef void destructor_func(const void*);
402
403/**
404 * Tx Queue for DMA. Queue consists of circular buffer of
405 * BD's and required locking structures.
406 */
407struct clx2_tx_queue {
408 struct clx2_queue q;
409 struct tfd_frame* bd;
410 struct ieee80211_txb **txb;
411};
412
413/*
414 * RX related structures and functions
415 */
416#define RX_FREE_BUFFERS 32
417#define RX_LOW_WATERMARK 8
418
419#define SUP_RATE_11A_MAX_NUM_CHANNELS (8)
420#define SUP_RATE_11B_MAX_NUM_CHANNELS (4)
421#define SUP_RATE_11G_MAX_NUM_CHANNELS (12)
422
423// Used for passing to driver number of successes and failures per rate
424struct rate_histogram
425{
426 union {
427 u32 a[SUP_RATE_11A_MAX_NUM_CHANNELS];
428 u32 b[SUP_RATE_11B_MAX_NUM_CHANNELS];
429 u32 g[SUP_RATE_11G_MAX_NUM_CHANNELS];
430 } success;
431 union {
432 u32 a[SUP_RATE_11A_MAX_NUM_CHANNELS];
433 u32 b[SUP_RATE_11B_MAX_NUM_CHANNELS];
434 u32 g[SUP_RATE_11G_MAX_NUM_CHANNELS];
435 } failed;
436} __attribute__ ((packed));
437
438/* statistics command response */
439struct ipw_cmd_stats {
440 u8 cmd_id;
441 u8 seq_num;
442 u16 good_sfd;
443 u16 bad_plcp;
444 u16 wrong_bssid;
445 u16 valid_mpdu;
446 u16 bad_mac_header;
447 u16 reserved_frame_types;
448 u16 rx_ina;
449 u16 bad_crc32;
450 u16 invalid_cts;
451 u16 invalid_acks;
452 u16 long_distance_ina_fina;
453 u16 dsp_silence_unreachable;
454 u16 accumulated_rssi;
455 u16 rx_ovfl_frame_tossed;
456 u16 rssi_silence_threshold;
457 u16 rx_ovfl_frame_supplied;
458 u16 last_rx_frame_signal;
459 u16 last_rx_frame_noise;
460 u16 rx_autodetec_no_ofdm;
461 u16 rx_autodetec_no_barker;
462 u16 reserved;
463} __attribute__ ((packed));
464
465struct notif_channel_result {
466 u8 channel_num;
467 struct ipw_cmd_stats stats;
468 u8 uReserved;
469} __attribute__ ((packed));
470
471struct notif_scan_complete {
472 u8 scan_type;
473 u8 num_channels;
474 u8 status;
475 u8 reserved;
476} __attribute__ ((packed));
477
478struct notif_frag_length {
479 u16 frag_length;
480 u16 reserved;
481} __attribute__ ((packed));
482
483struct notif_beacon_state {
484 u32 state;
485 u32 number;
486} __attribute__ ((packed));
487
488struct notif_tgi_tx_key {
489 u8 key_state;
490 u8 security_type;
491 u8 station_index;
492 u8 reserved;
493} __attribute__ ((packed));
494
495struct notif_link_deterioration {
496 struct ipw_cmd_stats stats;
497 u8 rate;
498 u8 modulation;
499 struct rate_histogram histogram;
500 u8 reserved1;
501 u16 reserved2;
502} __attribute__ ((packed));
503
504struct notif_association {
505 u8 state;
506} __attribute__ ((packed));
507
508struct notif_authenticate {
509 u8 state;
510 struct machdr24 addr;
511 u16 status;
512} __attribute__ ((packed));
513
514struct notif_calibration {
515 u8 data[104];
516} __attribute__ ((packed));
517
518struct notif_noise {
519 u32 value;
520} __attribute__ ((packed));
521
522struct ipw_rx_notification {
523 u8 reserved[8];
524 u8 subtype;
525 u8 flags;
526 u16 size;
527 union {
528 struct notif_association assoc;
529 struct notif_authenticate auth;
530 struct notif_channel_result channel_result;
531 struct notif_scan_complete scan_complete;
532 struct notif_frag_length frag_len;
533 struct notif_beacon_state beacon_state;
534 struct notif_tgi_tx_key tgi_tx_key;
535 struct notif_link_deterioration link_deterioration;
536 struct notif_calibration calibration;
537 struct notif_noise noise;
538 u8 raw[0];
539 } u;
540} __attribute__ ((packed));
541
542struct ipw_rx_frame {
543 u32 reserved1;
544 u8 parent_tsf[4]; // fw_use[0] is boolean for OUR_TSF_IS_GREATER
545 u8 received_channel; // The channel that this frame was received on.
546 // Note that for .11b this does not have to be
547 // the same as the channel that it was sent.
548 // Filled by LMAC
549 u8 frameStatus;
550 u8 rate;
551 u8 rssi;
552 u8 agc;
553 u8 rssi_dbm;
554 u16 signal;
555 u16 noise;
556 u8 antennaAndPhy;
557 u8 control; // control bit should be on in bg
558 u8 rtscts_rate; // rate of rts or cts (in rts cts sequence rate
559 // is identical)
560 u8 rtscts_seen; // 0x1 RTS seen ; 0x2 CTS seen
561 u16 length;
562 u8 data[0];
563} __attribute__ ((packed));
564
565struct ipw_rx_header {
566 u8 message_type;
567 u8 rx_seq_num;
568 u8 control_bits;
569 u8 reserved;
570} __attribute__ ((packed));
571
572struct ipw_rx_packet
573{
574 struct ipw_rx_header header;
575 union {
576 struct ipw_rx_frame frame;
577 struct ipw_rx_notification notification;
578 } u;
579} __attribute__ ((packed));
580
581#define IPW_RX_NOTIFICATION_SIZE sizeof(struct ipw_rx_header) + 12
582#define IPW_RX_FRAME_SIZE sizeof(struct ipw_rx_header) + \
583 sizeof(struct ipw_rx_frame)
584
585struct ipw_rx_mem_buffer {
586 dma_addr_t dma_addr;
587 struct ipw_rx_buffer *rxb;
588 struct sk_buff *skb;
589 struct list_head list;
590}; /* Not transferred over network, so not __attribute__ ((packed)) */
591
592struct ipw_rx_queue {
593 struct ipw_rx_mem_buffer pool[RX_QUEUE_SIZE + RX_FREE_BUFFERS];
594 struct ipw_rx_mem_buffer *queue[RX_QUEUE_SIZE];
595 u32 processed; /* Internal index to last handled Rx packet */
596 u32 read; /* Shared index to newest available Rx buffer */
597 u32 write; /* Shared index to oldest written Rx packet */
598 u32 free_count;/* Number of pre-allocated buffers in rx_free */
599 /* Each of these lists is used as a FIFO for ipw_rx_mem_buffers */
600 struct list_head rx_free; /* Own an SKBs */
601 struct list_head rx_used; /* No SKB allocated */
602 spinlock_t lock;
603}; /* Not transferred over network, so not __attribute__ ((packed)) */
604
605
606struct alive_command_responce {
607 u8 alive_command;
608 u8 sequence_number;
609 u16 software_revision;
610 u8 device_identifier;
611 u8 reserved1[5];
612 u16 reserved2;
613 u16 reserved3;
614 u16 clock_settle_time;
615 u16 powerup_settle_time;
616 u16 reserved4;
617 u8 time_stamp[5]; /* month, day, year, hours, minutes */
618 u8 ucode_valid;
619} __attribute__ ((packed));
620
621#define IPW_MAX_RATES 12
622
623struct ipw_rates {
624 u8 num_rates;
625 u8 rates[IPW_MAX_RATES];
626} __attribute__ ((packed));
627
628struct command_block
629{
630 unsigned int control;
631 u32 source_addr;
632 u32 dest_addr;
633 unsigned int status;
634} __attribute__ ((packed));
635
636#define CB_NUMBER_OF_ELEMENTS_SMALL 64
637struct fw_image_desc
638{
639 unsigned long last_cb_index;
640 unsigned long current_cb_index;
641 struct command_block cb_list[CB_NUMBER_OF_ELEMENTS_SMALL];
642 void * v_addr;
643 unsigned long p_addr;
644 unsigned long len;
645};
646
647struct ipw_sys_config
648{
649 u8 bt_coexistence;
650 u8 reserved1;
651 u8 answer_broadcast_ssid_probe;
652 u8 accept_all_data_frames;
653 u8 accept_non_directed_frames;
654 u8 exclude_unicast_unencrypted;
655 u8 disable_unicast_decryption;
656 u8 exclude_multicast_unencrypted;
657 u8 disable_multicast_decryption;
658 u8 antenna_diversity;
659 u8 pass_crc_to_host;
660 u8 dot11g_auto_detection;
661 u8 enable_cts_to_self;
662 u8 enable_multicast_filtering;
663 u8 bt_coexist_collision_thr;
664 u8 reserved2;
665 u8 accept_all_mgmt_bcpr;
666 u8 accept_all_mgtm_frames;
667 u8 pass_noise_stats_to_host;
668 u8 reserved3;
669} __attribute__ ((packed));
670
671struct ipw_multicast_addr
672{
673 u8 num_of_multicast_addresses;
674 u8 reserved[3];
675 u8 mac1[6];
676 u8 mac2[6];
677 u8 mac3[6];
678 u8 mac4[6];
679} __attribute__ ((packed));
680
681struct ipw_wep_key
682{
683 u8 cmd_id;
684 u8 seq_num;
685 u8 key_index;
686 u8 key_size;
687 u8 key[16];
688} __attribute__ ((packed));
689
690struct ipw_tgi_tx_key
691{
692 u8 key_id;
693 u8 security_type;
694 u8 station_index;
695 u8 flags;
696 u8 key[16];
697 u32 tx_counter[2];
698} __attribute__ ((packed));
699
700#define IPW_SCAN_CHANNELS 54
701
702struct ipw_scan_request
703{
704 u8 scan_type;
705 u16 dwell_time;
706 u8 channels_list[IPW_SCAN_CHANNELS];
707 u8 channels_reserved[3];
708} __attribute__ ((packed));
709
710enum {
711 IPW_SCAN_PASSIVE_TILL_FIRST_BEACON_SCAN = 0,
712 IPW_SCAN_PASSIVE_FULL_DWELL_SCAN,
713 IPW_SCAN_ACTIVE_DIRECT_SCAN,
714 IPW_SCAN_ACTIVE_BROADCAST_SCAN,
715 IPW_SCAN_ACTIVE_BROADCAST_AND_DIRECT_SCAN,
716 IPW_SCAN_TYPES
717};
718
719struct ipw_scan_request_ext
720{
721 u32 full_scan_index;
722 u8 channels_list[IPW_SCAN_CHANNELS];
723 u8 scan_type[IPW_SCAN_CHANNELS / 2];
724 u8 reserved;
725 u16 dwell_time[IPW_SCAN_TYPES];
726} __attribute__ ((packed));
727
728extern inline u8 ipw_get_scan_type(struct ipw_scan_request_ext *scan, u8 index)
729{
730 if (index % 2)
731 return scan->scan_type[index / 2] & 0x0F;
732 else
733 return (scan->scan_type[index / 2] & 0xF0) >> 4;
734}
735
736extern inline void ipw_set_scan_type(struct ipw_scan_request_ext *scan,
737 u8 index, u8 scan_type)
738{
739 if (index % 2)
740 scan->scan_type[index / 2] =
741 (scan->scan_type[index / 2] & 0xF0) |
742 (scan_type & 0x0F);
743 else
744 scan->scan_type[index / 2] =
745 (scan->scan_type[index / 2] & 0x0F) |
746 ((scan_type & 0x0F) << 4);
747}
748
749struct ipw_associate
750{
751 u8 channel;
752 u8 auth_type:4,
753 auth_key:4;
754 u8 assoc_type;
755 u8 reserved;
756 u16 policy_support;
757 u8 preamble_length;
758 u8 ieee_mode;
759 u8 bssid[ETH_ALEN];
760 u32 assoc_tsf_msw;
761 u32 assoc_tsf_lsw;
762 u16 capability;
763 u16 listen_interval;
764 u16 beacon_interval;
765 u8 dest[ETH_ALEN];
766 u16 atim_window;
767 u8 smr;
768 u8 reserved1;
769 u16 reserved2;
770} __attribute__ ((packed));
771
772struct ipw_supported_rates
773{
774 u8 ieee_mode;
775 u8 num_rates;
776 u8 purpose;
777 u8 reserved;
778 u8 supported_rates[IPW_MAX_RATES];
779} __attribute__ ((packed));
780
781struct ipw_rts_threshold
782{
783 u16 rts_threshold;
784 u16 reserved;
785} __attribute__ ((packed));
786
787struct ipw_frag_threshold
788{
789 u16 frag_threshold;
790 u16 reserved;
791} __attribute__ ((packed));
792
793struct ipw_retry_limit
794{
795 u8 short_retry_limit;
796 u8 long_retry_limit;
797 u16 reserved;
798} __attribute__ ((packed));
799
800struct ipw_dino_config
801{
802 u32 dino_config_addr;
803 u16 dino_config_size;
804 u8 dino_response;
805 u8 reserved;
806} __attribute__ ((packed));
807
808struct ipw_aironet_info
809{
810 u8 id;
811 u8 length;
812 u16 reserved;
813} __attribute__ ((packed));
814
815struct ipw_rx_key
816{
817 u8 station_index;
818 u8 key_type;
819 u8 key_id;
820 u8 key_flag;
821 u8 key[16];
822 u8 station_address[6];
823 u8 key_index;
824 u8 reserved;
825} __attribute__ ((packed));
826
827struct ipw_country_channel_info
828{
829 u8 first_channel;
830 u8 no_channels;
831 s8 max_tx_power;
832} __attribute__ ((packed));
833
834struct ipw_country_info
835{
836 u8 id;
837 u8 length;
838 u8 country_str[3];
839 struct ipw_country_channel_info groups[7];
840} __attribute__ ((packed));
841
842struct ipw_channel_tx_power
843{
844 u8 channel_number;
845 s8 tx_power;
846} __attribute__ ((packed));
847
848#define SCAN_ASSOCIATED_INTERVAL (HZ)
849#define SCAN_INTERVAL (HZ / 10)
850#define MAX_A_CHANNELS 37
851#define MAX_B_CHANNELS 14
852
853struct ipw_tx_power
854{
855 u8 num_channels;
856 u8 ieee_mode;
857 struct ipw_channel_tx_power channels_tx_power[MAX_A_CHANNELS];
858} __attribute__ ((packed));
859
860struct ipw_qos_parameters
861{
862 u16 cw_min[4];
863 u16 cw_max[4];
864 u8 aifs[4];
865 u8 flag[4];
866 u16 tx_op_limit[4];
867} __attribute__ ((packed));
868
869struct ipw_rsn_capabilities
870{
871 u8 id;
872 u8 length;
873 u16 version;
874} __attribute__ ((packed));
875
876struct ipw_sensitivity_calib
877{
878 u16 beacon_rssi_raw;
879 u16 reserved;
880} __attribute__ ((packed));
881
882/**
883 * Host command structure.
884 *
885 * On input, the following fields should be filled:
886 * - cmd
887 * - len
888 * - status_len
889 * - param (if needed)
890 *
891 * On output,
892 * - \a status contains status;
893 * - \a param filled with status parameters.
894 */
895struct ipw_cmd {
896 u32 cmd; /**< Host command */
897 u32 status; /**< Status */
898 u32 status_len; /**< How many 32 bit parameters in the status */
899 u32 len; /**< incoming parameters length, bytes */
900 /**
901 * command parameters.
902 * There should be enough space for incoming and
903 * outcoming parameters.
904 * Incoming parameters listed 1-st, followed by outcoming params.
905 * nParams=(len+3)/4+status_len
906 */
907 u32 param[0];
908} __attribute__ ((packed));
909
910#define STATUS_HCMD_ACTIVE (1<<0) /**< host command in progress */
911
912#define STATUS_INT_ENABLED (1<<1)
913#define STATUS_RF_KILL_HW (1<<2)
914#define STATUS_RF_KILL_SW (1<<3)
915#define STATUS_RF_KILL_MASK (STATUS_RF_KILL_HW | STATUS_RF_KILL_SW)
916
917#define STATUS_INIT (1<<5)
918#define STATUS_AUTH (1<<6)
919#define STATUS_ASSOCIATED (1<<7)
920#define STATUS_STATE_MASK (STATUS_INIT | STATUS_AUTH | STATUS_ASSOCIATED)
921
922#define STATUS_ASSOCIATING (1<<8)
923#define STATUS_DISASSOCIATING (1<<9)
924#define STATUS_ROAMING (1<<10)
925#define STATUS_EXIT_PENDING (1<<11)
926#define STATUS_DISASSOC_PENDING (1<<12)
927#define STATUS_STATE_PENDING (1<<13)
928
929#define STATUS_SCAN_PENDING (1<<20)
930#define STATUS_SCANNING (1<<21)
931#define STATUS_SCAN_ABORTING (1<<22)
932
933#define STATUS_INDIRECT_BYTE (1<<28) /* sysfs entry configured for access */
934#define STATUS_INDIRECT_DWORD (1<<29) /* sysfs entry configured for access */
935#define STATUS_DIRECT_DWORD (1<<30) /* sysfs entry configured for access */
936
937#define STATUS_SECURITY_UPDATED (1<<31) /* Security sync needed */
938
939#define CFG_STATIC_CHANNEL (1<<0) /* Restrict assoc. to single channel */
940#define CFG_STATIC_ESSID (1<<1) /* Restrict assoc. to single SSID */
941#define CFG_STATIC_BSSID (1<<2) /* Restrict assoc. to single BSSID */
942#define CFG_CUSTOM_MAC (1<<3)
943#define CFG_PREAMBLE (1<<4)
944#define CFG_ADHOC_PERSIST (1<<5)
945#define CFG_ASSOCIATE (1<<6)
946#define CFG_FIXED_RATE (1<<7)
947#define CFG_ADHOC_CREATE (1<<8)
948
949#define CAP_SHARED_KEY (1<<0) /* Off = OPEN */
950#define CAP_PRIVACY_ON (1<<1) /* Off = No privacy */
951
952#define MAX_STATIONS 32
953#define IPW_INVALID_STATION (0xff)
954
955struct ipw_station_entry {
956 u8 mac_addr[ETH_ALEN];
957 u8 reserved;
958 u8 support_mode;
959};
960
961#define AVG_ENTRIES 8
962struct average {
963 s16 entries[AVG_ENTRIES];
964 u8 pos;
965 u8 init;
966 s32 sum;
967};
968
969struct ipw_priv {
970 /* ieee device used by generic ieee processing code */
971 struct ieee80211_device *ieee;
972 struct ieee80211_security sec;
973
974 /* spinlock */
975 spinlock_t lock;
976
977 /* basic pci-network driver stuff */
978 struct pci_dev *pci_dev;
979 struct net_device *net_dev;
980
981 /* pci hardware address support */
982 void __iomem *hw_base;
983 unsigned long hw_len;
984
985 struct fw_image_desc sram_desc;
986
987 /* result of ucode download */
988 struct alive_command_responce dino_alive;
989
990 wait_queue_head_t wait_command_queue;
991 wait_queue_head_t wait_state;
992
993 /* Rx and Tx DMA processing queues */
994 struct ipw_rx_queue *rxq;
995 struct clx2_tx_queue txq_cmd;
996 struct clx2_tx_queue txq[4];
997 u32 status;
998 u32 config;
999 u32 capability;
1000
1001 u8 last_rx_rssi;
1002 u8 last_noise;
1003 struct average average_missed_beacons;
1004 struct average average_rssi;
1005 struct average average_noise;
1006 u32 port_type;
1007 int rx_bufs_min; /**< minimum number of bufs in Rx queue */
1008 int rx_pend_max; /**< maximum pending buffers for one IRQ */
1009 u32 hcmd_seq; /**< sequence number for hcmd */
1010 u32 missed_beacon_threshold;
1011 u32 roaming_threshold;
1012
1013 struct ipw_associate assoc_request;
1014 struct ieee80211_network *assoc_network;
1015
1016 unsigned long ts_scan_abort;
1017 struct ipw_supported_rates rates;
1018 struct ipw_rates phy[3]; /**< PHY restrictions, per band */
1019 struct ipw_rates supp; /**< software defined */
1020 struct ipw_rates extended; /**< use for corresp. IE, AP only */
1021
1022 struct notif_link_deterioration last_link_deterioration; /** for statistics */
1023 struct ipw_cmd* hcmd; /**< host command currently executed */
1024
1025 wait_queue_head_t hcmd_wq; /**< host command waits for execution */
1026 u32 tsf_bcn[2]; /**< TSF from latest beacon */
1027
1028 struct notif_calibration calib; /**< last calibration */
1029
1030 /* ordinal interface with firmware */
1031 u32 table0_addr;
1032 u32 table0_len;
1033 u32 table1_addr;
1034 u32 table1_len;
1035 u32 table2_addr;
1036 u32 table2_len;
1037
1038 /* context information */
1039 u8 essid[IW_ESSID_MAX_SIZE];
1040 u8 essid_len;
1041 u8 nick[IW_ESSID_MAX_SIZE];
1042 u16 rates_mask;
1043 u8 channel;
1044 struct ipw_sys_config sys_config;
1045 u32 power_mode;
1046 u8 bssid[ETH_ALEN];
1047 u16 rts_threshold;
1048 u8 mac_addr[ETH_ALEN];
1049 u8 num_stations;
1050 u8 stations[MAX_STATIONS][ETH_ALEN];
1051
1052 u32 notif_missed_beacons;
1053
1054 /* Statistics and counters normalized with each association */
1055 u32 last_missed_beacons;
1056 u32 last_tx_packets;
1057 u32 last_rx_packets;
1058 u32 last_tx_failures;
1059 u32 last_rx_err;
1060 u32 last_rate;
1061
1062 u32 missed_adhoc_beacons;
1063 u32 missed_beacons;
1064 u32 rx_packets;
1065 u32 tx_packets;
1066 u32 quality;
1067
1068 /* eeprom */
1069 u8 eeprom[0x100]; /* 256 bytes of eeprom */
1070 int eeprom_delay;
1071
1072 struct iw_statistics wstats;
1073
1074 struct workqueue_struct *workqueue;
1075
1076 struct work_struct adhoc_check;
1077 struct work_struct associate;
1078 struct work_struct disassociate;
1079 struct work_struct rx_replenish;
1080 struct work_struct request_scan;
1081 struct work_struct adapter_restart;
1082 struct work_struct rf_kill;
1083 struct work_struct up;
1084 struct work_struct down;
1085 struct work_struct gather_stats;
1086 struct work_struct abort_scan;
1087 struct work_struct roam;
1088 struct work_struct scan_check;
1089
1090 struct tasklet_struct irq_tasklet;
1091
1092
1093#define IPW_2200BG 1
1094#define IPW_2915ABG 2
1095 u8 adapter;
1096
1097#define IPW_DEFAULT_TX_POWER 0x14
1098 u8 tx_power;
1099
1100#ifdef CONFIG_PM
1101 u32 pm_state[16];
1102#endif
1103
1104 /* network state */
1105
1106 /* Used to pass the current INTA value from ISR to Tasklet */
1107 u32 isr_inta;
1108
1109 /* debugging info */
1110 u32 indirect_dword;
1111 u32 direct_dword;
1112 u32 indirect_byte;
1113}; /*ipw_priv */
1114
1115
1116/* debug macros */
1117
1118#ifdef CONFIG_IPW_DEBUG
1119#define IPW_DEBUG(level, fmt, args...) \
1120do { if (ipw_debug_level & (level)) \
1121 printk(KERN_DEBUG DRV_NAME": %c %s " fmt, \
1122 in_interrupt() ? 'I' : 'U', __FUNCTION__ , ## args); } while (0)
1123#else
1124#define IPW_DEBUG(level, fmt, args...) do {} while (0)
1125#endif /* CONFIG_IPW_DEBUG */
1126
1127/*
1128 * To use the debug system;
1129 *
1130 * If you are defining a new debug classification, simply add it to the #define
1131 * list here in the form of:
1132 *
1133 * #define IPW_DL_xxxx VALUE
1134 *
1135 * shifting value to the left one bit from the previous entry. xxxx should be
1136 * the name of the classification (for example, WEP)
1137 *
1138 * You then need to either add a IPW_xxxx_DEBUG() macro definition for your
1139 * classification, or use IPW_DEBUG(IPW_DL_xxxx, ...) whenever you want
1140 * to send output to that classification.
1141 *
1142 * To add your debug level to the list of levels seen when you perform
1143 *
1144 * % cat /proc/net/ipw/debug_level
1145 *
1146 * you simply need to add your entry to the ipw_debug_levels array.
1147 *
1148 * If you do not see debug_level in /proc/net/ipw then you do not have
1149 * CONFIG_IPW_DEBUG defined in your kernel configuration
1150 *
1151 */
1152
1153#define IPW_DL_ERROR (1<<0)
1154#define IPW_DL_WARNING (1<<1)
1155#define IPW_DL_INFO (1<<2)
1156#define IPW_DL_WX (1<<3)
1157#define IPW_DL_HOST_COMMAND (1<<5)
1158#define IPW_DL_STATE (1<<6)
1159
1160#define IPW_DL_NOTIF (1<<10)
1161#define IPW_DL_SCAN (1<<11)
1162#define IPW_DL_ASSOC (1<<12)
1163#define IPW_DL_DROP (1<<13)
1164#define IPW_DL_IOCTL (1<<14)
1165
1166#define IPW_DL_MANAGE (1<<15)
1167#define IPW_DL_FW (1<<16)
1168#define IPW_DL_RF_KILL (1<<17)
1169#define IPW_DL_FW_ERRORS (1<<18)
1170
1171
1172#define IPW_DL_ORD (1<<20)
1173
1174#define IPW_DL_FRAG (1<<21)
1175#define IPW_DL_WEP (1<<22)
1176#define IPW_DL_TX (1<<23)
1177#define IPW_DL_RX (1<<24)
1178#define IPW_DL_ISR (1<<25)
1179#define IPW_DL_FW_INFO (1<<26)
1180#define IPW_DL_IO (1<<27)
1181#define IPW_DL_TRACE (1<<28)
1182
1183#define IPW_DL_STATS (1<<29)
1184
1185
1186#define IPW_ERROR(f, a...) printk(KERN_ERR DRV_NAME ": " f, ## a)
1187#define IPW_WARNING(f, a...) printk(KERN_WARNING DRV_NAME ": " f, ## a)
1188#define IPW_DEBUG_INFO(f, a...) IPW_DEBUG(IPW_DL_INFO, f, ## a)
1189
1190#define IPW_DEBUG_WX(f, a...) IPW_DEBUG(IPW_DL_WX, f, ## a)
1191#define IPW_DEBUG_SCAN(f, a...) IPW_DEBUG(IPW_DL_SCAN, f, ## a)
1192#define IPW_DEBUG_STATUS(f, a...) IPW_DEBUG(IPW_DL_STATUS, f, ## a)
1193#define IPW_DEBUG_TRACE(f, a...) IPW_DEBUG(IPW_DL_TRACE, f, ## a)
1194#define IPW_DEBUG_RX(f, a...) IPW_DEBUG(IPW_DL_RX, f, ## a)
1195#define IPW_DEBUG_TX(f, a...) IPW_DEBUG(IPW_DL_TX, f, ## a)
1196#define IPW_DEBUG_ISR(f, a...) IPW_DEBUG(IPW_DL_ISR, f, ## a)
1197#define IPW_DEBUG_MANAGEMENT(f, a...) IPW_DEBUG(IPW_DL_MANAGE, f, ## a)
1198#define IPW_DEBUG_WEP(f, a...) IPW_DEBUG(IPW_DL_WEP, f, ## a)
1199#define IPW_DEBUG_HC(f, a...) IPW_DEBUG(IPW_DL_HOST_COMMAND, f, ## a)
1200#define IPW_DEBUG_FRAG(f, a...) IPW_DEBUG(IPW_DL_FRAG, f, ## a)
1201#define IPW_DEBUG_FW(f, a...) IPW_DEBUG(IPW_DL_FW, f, ## a)
1202#define IPW_DEBUG_RF_KILL(f, a...) IPW_DEBUG(IPW_DL_RF_KILL, f, ## a)
1203#define IPW_DEBUG_DROP(f, a...) IPW_DEBUG(IPW_DL_DROP, f, ## a)
1204#define IPW_DEBUG_IO(f, a...) IPW_DEBUG(IPW_DL_IO, f, ## a)
1205#define IPW_DEBUG_ORD(f, a...) IPW_DEBUG(IPW_DL_ORD, f, ## a)
1206#define IPW_DEBUG_FW_INFO(f, a...) IPW_DEBUG(IPW_DL_FW_INFO, f, ## a)
1207#define IPW_DEBUG_NOTIF(f, a...) IPW_DEBUG(IPW_DL_NOTIF, f, ## a)
1208#define IPW_DEBUG_STATE(f, a...) IPW_DEBUG(IPW_DL_STATE | IPW_DL_ASSOC | IPW_DL_INFO, f, ## a)
1209#define IPW_DEBUG_ASSOC(f, a...) IPW_DEBUG(IPW_DL_ASSOC | IPW_DL_INFO, f, ## a)
1210#define IPW_DEBUG_STATS(f, a...) IPW_DEBUG(IPW_DL_STATS, f, ## a)
1211
1212#include <linux/ctype.h>
1213
1214/*
1215* Register bit definitions
1216*/
1217
1218/* Dino control registers bits */
1219
1220#define DINO_ENABLE_SYSTEM 0x80
1221#define DINO_ENABLE_CS 0x40
1222#define DINO_RXFIFO_DATA 0x01
1223#define DINO_CONTROL_REG 0x00200000
1224
1225#define CX2_INTA_RW 0x00000008
1226#define CX2_INTA_MASK_R 0x0000000C
1227#define CX2_INDIRECT_ADDR 0x00000010
1228#define CX2_INDIRECT_DATA 0x00000014
1229#define CX2_AUTOINC_ADDR 0x00000018
1230#define CX2_AUTOINC_DATA 0x0000001C
1231#define CX2_RESET_REG 0x00000020
1232#define CX2_GP_CNTRL_RW 0x00000024
1233
1234#define CX2_READ_INT_REGISTER 0xFF4
1235
1236#define CX2_GP_CNTRL_BIT_INIT_DONE 0x00000004
1237
1238#define CX2_REGISTER_DOMAIN1_END 0x00001000
1239#define CX2_SRAM_READ_INT_REGISTER 0x00000ff4
1240
1241#define CX2_SHARED_LOWER_BOUND 0x00000200
1242#define CX2_INTERRUPT_AREA_LOWER_BOUND 0x00000f80
1243
1244#define CX2_NIC_SRAM_LOWER_BOUND 0x00000000
1245#define CX2_NIC_SRAM_UPPER_BOUND 0x00030000
1246
1247#define CX2_BIT_INT_HOST_SRAM_READ_INT_REGISTER (1 << 29)
1248#define CX2_GP_CNTRL_BIT_CLOCK_READY 0x00000001
1249#define CX2_GP_CNTRL_BIT_HOST_ALLOWS_STANDBY 0x00000002
1250
1251/*
1252 * RESET Register Bit Indexes
1253 */
1254#define CBD_RESET_REG_PRINCETON_RESET 0x00000001 /* Bit 0 (LSB) */
1255#define CX2_RESET_REG_SW_RESET 0x00000080 /* Bit 7 */
1256#define CX2_RESET_REG_MASTER_DISABLED 0x00000100 /* Bit 8 */
1257#define CX2_RESET_REG_STOP_MASTER 0x00000200 /* Bit 9 */
1258#define CX2_ARC_KESHET_CONFIG 0x08000000 /* Bit 27 */
1259#define CX2_START_STANDBY 0x00000004 /* Bit 2 */
1260
1261#define CX2_CSR_CIS_UPPER_BOUND 0x00000200
1262#define CX2_DOMAIN_0_END 0x1000
1263#define CLX_MEM_BAR_SIZE 0x1000
1264
1265#define CX2_BASEBAND_CONTROL_STATUS 0X00200000
1266#define CX2_BASEBAND_TX_FIFO_WRITE 0X00200004
1267#define CX2_BASEBAND_RX_FIFO_READ 0X00200004
1268#define CX2_BASEBAND_CONTROL_STORE 0X00200010
1269
1270#define CX2_INTERNAL_CMD_EVENT 0X00300004
1271#define CX2_BASEBAND_POWER_DOWN 0x00000001
1272
1273#define CX2_MEM_HALT_AND_RESET 0x003000e0
1274
1275/* defgroup bits_halt_reset MEM_HALT_AND_RESET register bits */
1276#define CX2_BIT_HALT_RESET_ON 0x80000000
1277#define CX2_BIT_HALT_RESET_OFF 0x00000000
1278
1279#define CB_LAST_VALID 0x20000000
1280#define CB_INT_ENABLED 0x40000000
1281#define CB_VALID 0x80000000
1282#define CB_SRC_LE 0x08000000
1283#define CB_DEST_LE 0x04000000
1284#define CB_SRC_AUTOINC 0x00800000
1285#define CB_SRC_IO_GATED 0x00400000
1286#define CB_DEST_AUTOINC 0x00080000
1287#define CB_SRC_SIZE_LONG 0x00200000
1288#define CB_DEST_SIZE_LONG 0x00020000
1289
1290
1291/* DMA DEFINES */
1292
1293#define DMA_CONTROL_SMALL_CB_CONST_VALUE 0x00540000
1294#define DMA_CB_STOP_AND_ABORT 0x00000C00
1295#define DMA_CB_START 0x00000100
1296
1297
1298#define CX2_SHARED_SRAM_SIZE 0x00030000
1299#define CX2_SHARED_SRAM_DMA_CONTROL 0x00027000
1300#define CB_MAX_LENGTH 0x1FFF
1301
1302#define CX2_HOST_EEPROM_DATA_SRAM_SIZE 0xA18
1303#define CX2_EEPROM_IMAGE_SIZE 0x100
1304
1305
1306/* DMA defs */
1307#define CX2_DMA_I_CURRENT_CB 0x003000D0
1308#define CX2_DMA_O_CURRENT_CB 0x003000D4
1309#define CX2_DMA_I_DMA_CONTROL 0x003000A4
1310#define CX2_DMA_I_CB_BASE 0x003000A0
1311
1312#define CX2_TX_CMD_QUEUE_BD_BASE (0x00000200)
1313#define CX2_TX_CMD_QUEUE_BD_SIZE (0x00000204)
1314#define CX2_TX_QUEUE_0_BD_BASE (0x00000208)
1315#define CX2_TX_QUEUE_0_BD_SIZE (0x0000020C)
1316#define CX2_TX_QUEUE_1_BD_BASE (0x00000210)
1317#define CX2_TX_QUEUE_1_BD_SIZE (0x00000214)
1318#define CX2_TX_QUEUE_2_BD_BASE (0x00000218)
1319#define CX2_TX_QUEUE_2_BD_SIZE (0x0000021C)
1320#define CX2_TX_QUEUE_3_BD_BASE (0x00000220)
1321#define CX2_TX_QUEUE_3_BD_SIZE (0x00000224)
1322#define CX2_RX_BD_BASE (0x00000240)
1323#define CX2_RX_BD_SIZE (0x00000244)
1324#define CX2_RFDS_TABLE_LOWER (0x00000500)
1325
1326#define CX2_TX_CMD_QUEUE_READ_INDEX (0x00000280)
1327#define CX2_TX_QUEUE_0_READ_INDEX (0x00000284)
1328#define CX2_TX_QUEUE_1_READ_INDEX (0x00000288)
1329#define CX2_TX_QUEUE_2_READ_INDEX (0x0000028C)
1330#define CX2_TX_QUEUE_3_READ_INDEX (0x00000290)
1331#define CX2_RX_READ_INDEX (0x000002A0)
1332
1333#define CX2_TX_CMD_QUEUE_WRITE_INDEX (0x00000F80)
1334#define CX2_TX_QUEUE_0_WRITE_INDEX (0x00000F84)
1335#define CX2_TX_QUEUE_1_WRITE_INDEX (0x00000F88)
1336#define CX2_TX_QUEUE_2_WRITE_INDEX (0x00000F8C)
1337#define CX2_TX_QUEUE_3_WRITE_INDEX (0x00000F90)
1338#define CX2_RX_WRITE_INDEX (0x00000FA0)
1339
1340/*
1341 * EEPROM Related Definitions
1342 */
1343
1344#define IPW_EEPROM_DATA_SRAM_ADDRESS (CX2_SHARED_LOWER_BOUND + 0x814)
1345#define IPW_EEPROM_DATA_SRAM_SIZE (CX2_SHARED_LOWER_BOUND + 0x818)
1346#define IPW_EEPROM_LOAD_DISABLE (CX2_SHARED_LOWER_BOUND + 0x81C)
1347#define IPW_EEPROM_DATA (CX2_SHARED_LOWER_BOUND + 0x820)
1348#define IPW_EEPROM_UPPER_ADDRESS (CX2_SHARED_LOWER_BOUND + 0x9E0)
1349
1350#define IPW_STATION_TABLE_LOWER (CX2_SHARED_LOWER_BOUND + 0xA0C)
1351#define IPW_STATION_TABLE_UPPER (CX2_SHARED_LOWER_BOUND + 0xB0C)
1352#define IPW_REQUEST_ATIM (CX2_SHARED_LOWER_BOUND + 0xB0C)
1353#define IPW_ATIM_SENT (CX2_SHARED_LOWER_BOUND + 0xB10)
1354#define IPW_WHO_IS_AWAKE (CX2_SHARED_LOWER_BOUND + 0xB14)
1355#define IPW_DURING_ATIM_WINDOW (CX2_SHARED_LOWER_BOUND + 0xB18)
1356
1357
1358#define MSB 1
1359#define LSB 0
1360#define WORD_TO_BYTE(_word) ((_word) * sizeof(u16))
1361
1362#define GET_EEPROM_ADDR(_wordoffset,_byteoffset) \
1363 ( WORD_TO_BYTE(_wordoffset) + (_byteoffset) )
1364
1365/* EEPROM access by BYTE */
1366#define EEPROM_PME_CAPABILITY (GET_EEPROM_ADDR(0x09,MSB)) /* 1 byte */
1367#define EEPROM_MAC_ADDRESS (GET_EEPROM_ADDR(0x21,LSB)) /* 6 byte */
1368#define EEPROM_VERSION (GET_EEPROM_ADDR(0x24,MSB)) /* 1 byte */
1369#define EEPROM_NIC_TYPE (GET_EEPROM_ADDR(0x25,LSB)) /* 1 byte */
1370#define EEPROM_SKU_CAPABILITY (GET_EEPROM_ADDR(0x25,MSB)) /* 1 byte */
1371#define EEPROM_COUNTRY_CODE (GET_EEPROM_ADDR(0x26,LSB)) /* 3 bytes */
1372#define EEPROM_IBSS_CHANNELS_BG (GET_EEPROM_ADDR(0x28,LSB)) /* 2 bytes */
1373#define EEPROM_IBSS_CHANNELS_A (GET_EEPROM_ADDR(0x29,MSB)) /* 5 bytes */
1374#define EEPROM_BSS_CHANNELS_BG (GET_EEPROM_ADDR(0x2c,LSB)) /* 2 bytes */
1375#define EEPROM_HW_VERSION (GET_EEPROM_ADDR(0x72,LSB)) /* 2 bytes */
1376
1377/* NIC type as found in the one byte EEPROM_NIC_TYPE offset*/
1378#define EEPROM_NIC_TYPE_STANDARD 0
1379#define EEPROM_NIC_TYPE_DELL 1
1380#define EEPROM_NIC_TYPE_FUJITSU 2
1381#define EEPROM_NIC_TYPE_IBM 3
1382#define EEPROM_NIC_TYPE_HP 4
1383
1384#define FW_MEM_REG_LOWER_BOUND 0x00300000
1385#define FW_MEM_REG_EEPROM_ACCESS (FW_MEM_REG_LOWER_BOUND + 0x40)
1386
1387#define EEPROM_BIT_SK (1<<0)
1388#define EEPROM_BIT_CS (1<<1)
1389#define EEPROM_BIT_DI (1<<2)
1390#define EEPROM_BIT_DO (1<<4)
1391
1392#define EEPROM_CMD_READ 0x2
1393
1394/* Interrupts masks */
1395#define CX2_INTA_NONE 0x00000000
1396
1397#define CX2_INTA_BIT_RX_TRANSFER 0x00000002
1398#define CX2_INTA_BIT_STATUS_CHANGE 0x00000010
1399#define CX2_INTA_BIT_BEACON_PERIOD_EXPIRED 0x00000020
1400
1401//Inta Bits for CF
1402#define CX2_INTA_BIT_TX_CMD_QUEUE 0x00000800
1403#define CX2_INTA_BIT_TX_QUEUE_1 0x00001000
1404#define CX2_INTA_BIT_TX_QUEUE_2 0x00002000
1405#define CX2_INTA_BIT_TX_QUEUE_3 0x00004000
1406#define CX2_INTA_BIT_TX_QUEUE_4 0x00008000
1407
1408#define CX2_INTA_BIT_SLAVE_MODE_HOST_CMD_DONE 0x00010000
1409
1410#define CX2_INTA_BIT_PREPARE_FOR_POWER_DOWN 0x00100000
1411#define CX2_INTA_BIT_POWER_DOWN 0x00200000
1412
1413#define CX2_INTA_BIT_FW_INITIALIZATION_DONE 0x01000000
1414#define CX2_INTA_BIT_FW_CARD_DISABLE_PHY_OFF_DONE 0x02000000
1415#define CX2_INTA_BIT_RF_KILL_DONE 0x04000000
1416#define CX2_INTA_BIT_FATAL_ERROR 0x40000000
1417#define CX2_INTA_BIT_PARITY_ERROR 0x80000000
1418
1419/* Interrupts enabled at init time. */
1420#define CX2_INTA_MASK_ALL \
1421 (CX2_INTA_BIT_TX_QUEUE_1 | \
1422 CX2_INTA_BIT_TX_QUEUE_2 | \
1423 CX2_INTA_BIT_TX_QUEUE_3 | \
1424 CX2_INTA_BIT_TX_QUEUE_4 | \
1425 CX2_INTA_BIT_TX_CMD_QUEUE | \
1426 CX2_INTA_BIT_RX_TRANSFER | \
1427 CX2_INTA_BIT_FATAL_ERROR | \
1428 CX2_INTA_BIT_PARITY_ERROR | \
1429 CX2_INTA_BIT_STATUS_CHANGE | \
1430 CX2_INTA_BIT_FW_INITIALIZATION_DONE | \
1431 CX2_INTA_BIT_BEACON_PERIOD_EXPIRED | \
1432 CX2_INTA_BIT_SLAVE_MODE_HOST_CMD_DONE | \
1433 CX2_INTA_BIT_PREPARE_FOR_POWER_DOWN | \
1434 CX2_INTA_BIT_POWER_DOWN | \
1435 CX2_INTA_BIT_RF_KILL_DONE )
1436
1437#define IPWSTATUS_ERROR_LOG (CX2_SHARED_LOWER_BOUND + 0x410)
1438#define IPW_EVENT_LOG (CX2_SHARED_LOWER_BOUND + 0x414)
1439
1440/* FW event log definitions */
1441#define EVENT_ELEM_SIZE (3 * sizeof(u32))
1442#define EVENT_START_OFFSET (1 * sizeof(u32) + 2 * sizeof(u16))
1443
1444/* FW error log definitions */
1445#define ERROR_ELEM_SIZE (7 * sizeof(u32))
1446#define ERROR_START_OFFSET (1 * sizeof(u32))
1447
1448enum {
1449 IPW_FW_ERROR_OK = 0,
1450 IPW_FW_ERROR_FAIL,
1451 IPW_FW_ERROR_MEMORY_UNDERFLOW,
1452 IPW_FW_ERROR_MEMORY_OVERFLOW,
1453 IPW_FW_ERROR_BAD_PARAM,
1454 IPW_FW_ERROR_BAD_CHECKSUM,
1455 IPW_FW_ERROR_NMI_INTERRUPT,
1456 IPW_FW_ERROR_BAD_DATABASE,
1457 IPW_FW_ERROR_ALLOC_FAIL,
1458 IPW_FW_ERROR_DMA_UNDERRUN,
1459 IPW_FW_ERROR_DMA_STATUS,
1460 IPW_FW_ERROR_DINOSTATUS_ERROR,
1461 IPW_FW_ERROR_EEPROMSTATUS_ERROR,
1462 IPW_FW_ERROR_SYSASSERT,
1463 IPW_FW_ERROR_FATAL_ERROR
1464};
1465
1466#define AUTH_OPEN 0
1467#define AUTH_SHARED_KEY 1
1468#define AUTH_IGNORE 3
1469
1470#define HC_ASSOCIATE 0
1471#define HC_REASSOCIATE 1
1472#define HC_DISASSOCIATE 2
1473#define HC_IBSS_START 3
1474#define HC_IBSS_RECONF 4
1475#define HC_DISASSOC_QUIET 5
1476
1477#define IPW_RATE_CAPABILITIES 1
1478#define IPW_RATE_CONNECT 0
1479
1480
1481/*
1482 * Rate values and masks
1483 */
1484#define IPW_TX_RATE_1MB 0x0A
1485#define IPW_TX_RATE_2MB 0x14
1486#define IPW_TX_RATE_5MB 0x37
1487#define IPW_TX_RATE_6MB 0x0D
1488#define IPW_TX_RATE_9MB 0x0F
1489#define IPW_TX_RATE_11MB 0x6E
1490#define IPW_TX_RATE_12MB 0x05
1491#define IPW_TX_RATE_18MB 0x07
1492#define IPW_TX_RATE_24MB 0x09
1493#define IPW_TX_RATE_36MB 0x0B
1494#define IPW_TX_RATE_48MB 0x01
1495#define IPW_TX_RATE_54MB 0x03
1496
1497#define IPW_ORD_TABLE_ID_MASK 0x0000FF00
1498#define IPW_ORD_TABLE_VALUE_MASK 0x000000FF
1499
1500#define IPW_ORD_TABLE_0_MASK 0x0000F000
1501#define IPW_ORD_TABLE_1_MASK 0x0000F100
1502#define IPW_ORD_TABLE_2_MASK 0x0000F200
1503#define IPW_ORD_TABLE_3_MASK 0x0000F300
1504#define IPW_ORD_TABLE_4_MASK 0x0000F400
1505#define IPW_ORD_TABLE_5_MASK 0x0000F500
1506#define IPW_ORD_TABLE_6_MASK 0x0000F600
1507#define IPW_ORD_TABLE_7_MASK 0x0000F700
1508
1509/*
1510 * Table 0 Entries (all entries are 32 bits)
1511 */
1512enum {
1513 IPW_ORD_STAT_TX_CURR_RATE = IPW_ORD_TABLE_0_MASK + 1,
1514 IPW_ORD_STAT_FRAG_TRESHOLD,
1515 IPW_ORD_STAT_RTS_THRESHOLD,
1516 IPW_ORD_STAT_TX_HOST_REQUESTS,
1517 IPW_ORD_STAT_TX_HOST_COMPLETE,
1518 IPW_ORD_STAT_TX_DIR_DATA,
1519 IPW_ORD_STAT_TX_DIR_DATA_B_1,
1520 IPW_ORD_STAT_TX_DIR_DATA_B_2,
1521 IPW_ORD_STAT_TX_DIR_DATA_B_5_5,
1522 IPW_ORD_STAT_TX_DIR_DATA_B_11,
1523 /* Hole */
1524
1525
1526
1527
1528
1529
1530
1531 IPW_ORD_STAT_TX_DIR_DATA_G_1 = IPW_ORD_TABLE_0_MASK + 19,
1532 IPW_ORD_STAT_TX_DIR_DATA_G_2,
1533 IPW_ORD_STAT_TX_DIR_DATA_G_5_5,
1534 IPW_ORD_STAT_TX_DIR_DATA_G_6,
1535 IPW_ORD_STAT_TX_DIR_DATA_G_9,
1536 IPW_ORD_STAT_TX_DIR_DATA_G_11,
1537 IPW_ORD_STAT_TX_DIR_DATA_G_12,
1538 IPW_ORD_STAT_TX_DIR_DATA_G_18,
1539 IPW_ORD_STAT_TX_DIR_DATA_G_24,
1540 IPW_ORD_STAT_TX_DIR_DATA_G_36,
1541 IPW_ORD_STAT_TX_DIR_DATA_G_48,
1542 IPW_ORD_STAT_TX_DIR_DATA_G_54,
1543 IPW_ORD_STAT_TX_NON_DIR_DATA,
1544 IPW_ORD_STAT_TX_NON_DIR_DATA_B_1,
1545 IPW_ORD_STAT_TX_NON_DIR_DATA_B_2,
1546 IPW_ORD_STAT_TX_NON_DIR_DATA_B_5_5,
1547 IPW_ORD_STAT_TX_NON_DIR_DATA_B_11,
1548 /* Hole */
1549
1550
1551
1552
1553
1554
1555
1556 IPW_ORD_STAT_TX_NON_DIR_DATA_G_1 = IPW_ORD_TABLE_0_MASK + 44,
1557 IPW_ORD_STAT_TX_NON_DIR_DATA_G_2,
1558 IPW_ORD_STAT_TX_NON_DIR_DATA_G_5_5,
1559 IPW_ORD_STAT_TX_NON_DIR_DATA_G_6,
1560 IPW_ORD_STAT_TX_NON_DIR_DATA_G_9,
1561 IPW_ORD_STAT_TX_NON_DIR_DATA_G_11,
1562 IPW_ORD_STAT_TX_NON_DIR_DATA_G_12,
1563 IPW_ORD_STAT_TX_NON_DIR_DATA_G_18,
1564 IPW_ORD_STAT_TX_NON_DIR_DATA_G_24,
1565 IPW_ORD_STAT_TX_NON_DIR_DATA_G_36,
1566 IPW_ORD_STAT_TX_NON_DIR_DATA_G_48,
1567 IPW_ORD_STAT_TX_NON_DIR_DATA_G_54,
1568 IPW_ORD_STAT_TX_RETRY,
1569 IPW_ORD_STAT_TX_FAILURE,
1570 IPW_ORD_STAT_RX_ERR_CRC,
1571 IPW_ORD_STAT_RX_ERR_ICV,
1572 IPW_ORD_STAT_RX_NO_BUFFER,
1573 IPW_ORD_STAT_FULL_SCANS,
1574 IPW_ORD_STAT_PARTIAL_SCANS,
1575 IPW_ORD_STAT_TGH_ABORTED_SCANS,
1576 IPW_ORD_STAT_TX_TOTAL_BYTES,
1577 IPW_ORD_STAT_CURR_RSSI_RAW,
1578 IPW_ORD_STAT_RX_BEACON,
1579 IPW_ORD_STAT_MISSED_BEACONS,
1580 IPW_ORD_TABLE_0_LAST
1581};
1582
1583#define IPW_RSSI_TO_DBM 112
1584
1585/* Table 1 Entries
1586 */
1587enum {
1588 IPW_ORD_TABLE_1_LAST = IPW_ORD_TABLE_1_MASK | 1,
1589};
1590
1591/*
1592 * Table 2 Entries
1593 *
1594 * FW_VERSION: 16 byte string
1595 * FW_DATE: 16 byte string (only 14 bytes used)
1596 * UCODE_VERSION: 4 byte version code
1597 * UCODE_DATE: 5 bytes code code
1598 * ADDAPTER_MAC: 6 byte MAC address
1599 * RTC: 4 byte clock
1600 */
1601enum {
1602 IPW_ORD_STAT_FW_VERSION = IPW_ORD_TABLE_2_MASK | 1,
1603 IPW_ORD_STAT_FW_DATE,
1604 IPW_ORD_STAT_UCODE_VERSION,
1605 IPW_ORD_STAT_UCODE_DATE,
1606 IPW_ORD_STAT_ADAPTER_MAC,
1607 IPW_ORD_STAT_RTC,
1608 IPW_ORD_TABLE_2_LAST
1609};
1610
1611/* Table 3 */
1612enum {
1613 IPW_ORD_STAT_TX_PACKET = IPW_ORD_TABLE_3_MASK | 0,
1614 IPW_ORD_STAT_TX_PACKET_FAILURE,
1615 IPW_ORD_STAT_TX_PACKET_SUCCESS,
1616 IPW_ORD_STAT_TX_PACKET_ABORTED,
1617 IPW_ORD_TABLE_3_LAST
1618};
1619
1620/* Table 4 */
1621enum {
1622 IPW_ORD_TABLE_4_LAST = IPW_ORD_TABLE_4_MASK
1623};
1624
1625/* Table 5 */
1626enum {
1627 IPW_ORD_STAT_AVAILABLE_AP_COUNT = IPW_ORD_TABLE_5_MASK,
1628 IPW_ORD_STAT_AP_ASSNS,
1629 IPW_ORD_STAT_ROAM,
1630 IPW_ORD_STAT_ROAM_CAUSE_MISSED_BEACONS,
1631 IPW_ORD_STAT_ROAM_CAUSE_UNASSOC,
1632 IPW_ORD_STAT_ROAM_CAUSE_RSSI,
1633 IPW_ORD_STAT_ROAM_CAUSE_LINK_QUALITY,
1634 IPW_ORD_STAT_ROAM_CAUSE_AP_LOAD_BALANCE,
1635 IPW_ORD_STAT_ROAM_CAUSE_AP_NO_TX,
1636 IPW_ORD_STAT_LINK_UP,
1637 IPW_ORD_STAT_LINK_DOWN,
1638 IPW_ORD_ANTENNA_DIVERSITY,
1639 IPW_ORD_CURR_FREQ,
1640 IPW_ORD_TABLE_5_LAST
1641};
1642
1643/* Table 6 */
1644enum {
1645 IPW_ORD_COUNTRY_CODE = IPW_ORD_TABLE_6_MASK,
1646 IPW_ORD_CURR_BSSID,
1647 IPW_ORD_CURR_SSID,
1648 IPW_ORD_TABLE_6_LAST
1649};
1650
1651/* Table 7 */
1652enum {
1653 IPW_ORD_STAT_PERCENT_MISSED_BEACONS = IPW_ORD_TABLE_7_MASK,
1654 IPW_ORD_STAT_PERCENT_TX_RETRIES,
1655 IPW_ORD_STAT_PERCENT_LINK_QUALITY,
1656 IPW_ORD_STAT_CURR_RSSI_DBM,
1657 IPW_ORD_TABLE_7_LAST
1658};
1659
1660#define IPW_ORDINALS_TABLE_LOWER (CX2_SHARED_LOWER_BOUND + 0x500)
1661#define IPW_ORDINALS_TABLE_0 (CX2_SHARED_LOWER_BOUND + 0x180)
1662#define IPW_ORDINALS_TABLE_1 (CX2_SHARED_LOWER_BOUND + 0x184)
1663#define IPW_ORDINALS_TABLE_2 (CX2_SHARED_LOWER_BOUND + 0x188)
1664#define IPW_MEM_FIXED_OVERRIDE (CX2_SHARED_LOWER_BOUND + 0x41C)
1665
1666struct ipw_fixed_rate {
1667 u16 tx_rates;
1668 u16 reserved;
1669} __attribute__ ((packed));
1670
1671#define CX2_INDIRECT_ADDR_MASK (~0x3ul)
1672
1673struct host_cmd {
1674 u8 cmd;
1675 u8 len;
1676 u16 reserved;
1677 u32 param[TFD_CMD_IMMEDIATE_PAYLOAD_LENGTH];
1678} __attribute__ ((packed));
1679
1680#define CFG_BT_COEXISTENCE_MIN 0x00
1681#define CFG_BT_COEXISTENCE_DEFER 0x02
1682#define CFG_BT_COEXISTENCE_KILL 0x04
1683#define CFG_BT_COEXISTENCE_WME_OVER_BT 0x08
1684#define CFG_BT_COEXISTENCE_OOB 0x10
1685#define CFG_BT_COEXISTENCE_MAX 0xFF
1686#define CFG_BT_COEXISTENCE_DEF 0x80 /* read Bt from EEPROM*/
1687
1688#define CFG_CTS_TO_ITSELF_ENABLED_MIN 0x0
1689#define CFG_CTS_TO_ITSELF_ENABLED_MAX 0x1
1690#define CFG_CTS_TO_ITSELF_ENABLED_DEF CFG_CTS_TO_ITSELF_ENABLED_MIN
1691
1692#define CFG_SYS_ANTENNA_BOTH 0x000
1693#define CFG_SYS_ANTENNA_A 0x001
1694#define CFG_SYS_ANTENNA_B 0x003
1695
1696/*
1697 * The definitions below were lifted off the ipw2100 driver, which only
1698 * supports 'b' mode, so I'm sure these are not exactly correct.
1699 *
1700 * Somebody fix these!!
1701 */
1702#define REG_MIN_CHANNEL 0
1703#define REG_MAX_CHANNEL 14
1704
1705#define REG_CHANNEL_MASK 0x00003FFF
1706#define IPW_IBSS_11B_DEFAULT_MASK 0x87ff
1707
1708static const long ipw_frequencies[] = {
1709 2412, 2417, 2422, 2427,
1710 2432, 2437, 2442, 2447,
1711 2452, 2457, 2462, 2467,
1712 2472, 2484
1713};
1714
1715#define FREQ_COUNT ARRAY_SIZE(ipw_frequencies)
1716
1717#define IPW_MAX_CONFIG_RETRIES 10
1718
1719static inline u32 frame_hdr_len(struct ieee80211_hdr *hdr)
1720{
1721 u32 retval;
1722 u16 fc;
1723
1724 retval = sizeof(struct ieee80211_hdr);
1725 fc = le16_to_cpu(hdr->frame_ctl);
1726
1727 /*
1728 * Function ToDS FromDS
1729 * IBSS 0 0
1730 * To AP 1 0
1731 * From AP 0 1
1732 * WDS (bridge) 1 1
1733 *
1734 * Only WDS frames use Address4 among them. --YZ
1735 */
1736 if (!(fc & IEEE80211_FCTL_TODS) || !(fc & IEEE80211_FCTL_FROMDS))
1737 retval -= ETH_ALEN;
1738
1739 return retval;
1740}
1741
1742#endif /* __ipw2200_h__ */
diff --git a/drivers/net/wireless/orinoco.c b/drivers/net/wireless/orinoco.c
index 9c2d07cde010..d7947358e49d 100644
--- a/drivers/net/wireless/orinoco.c
+++ b/drivers/net/wireless/orinoco.c
@@ -94,6 +94,8 @@
94#include <net/iw_handler.h> 94#include <net/iw_handler.h>
95#include <net/ieee80211.h> 95#include <net/ieee80211.h>
96 96
97#include <net/ieee80211.h>
98
97#include <asm/uaccess.h> 99#include <asm/uaccess.h>
98#include <asm/io.h> 100#include <asm/io.h>
99#include <asm/system.h> 101#include <asm/system.h>
@@ -101,7 +103,6 @@
101#include "hermes.h" 103#include "hermes.h"
102#include "hermes_rid.h" 104#include "hermes_rid.h"
103#include "orinoco.h" 105#include "orinoco.h"
104#include "ieee802_11.h"
105 106
106/********************************************************************/ 107/********************************************************************/
107/* Module information */ 108/* Module information */
@@ -150,7 +151,7 @@ static const u8 encaps_hdr[] = {0xaa, 0xaa, 0x03, 0x00, 0x00, 0x00};
150#define ENCAPS_OVERHEAD (sizeof(encaps_hdr) + 2) 151#define ENCAPS_OVERHEAD (sizeof(encaps_hdr) + 2)
151 152
152#define ORINOCO_MIN_MTU 256 153#define ORINOCO_MIN_MTU 256
153#define ORINOCO_MAX_MTU (IEEE802_11_DATA_LEN - ENCAPS_OVERHEAD) 154#define ORINOCO_MAX_MTU (IEEE80211_DATA_LEN - ENCAPS_OVERHEAD)
154 155
155#define SYMBOL_MAX_VER_LEN (14) 156#define SYMBOL_MAX_VER_LEN (14)
156#define USER_BAP 0 157#define USER_BAP 0
@@ -442,7 +443,7 @@ static int orinoco_change_mtu(struct net_device *dev, int new_mtu)
442 if ( (new_mtu < ORINOCO_MIN_MTU) || (new_mtu > ORINOCO_MAX_MTU) ) 443 if ( (new_mtu < ORINOCO_MIN_MTU) || (new_mtu > ORINOCO_MAX_MTU) )
443 return -EINVAL; 444 return -EINVAL;
444 445
445 if ( (new_mtu + ENCAPS_OVERHEAD + IEEE802_11_HLEN) > 446 if ( (new_mtu + ENCAPS_OVERHEAD + IEEE80211_HLEN) >
446 (priv->nicbuf_size - ETH_HLEN) ) 447 (priv->nicbuf_size - ETH_HLEN) )
447 return -EINVAL; 448 return -EINVAL;
448 449
@@ -918,7 +919,7 @@ static void __orinoco_ev_rx(struct net_device *dev, hermes_t *hw)
918 data. */ 919 data. */
919 return; 920 return;
920 } 921 }
921 if (length > IEEE802_11_DATA_LEN) { 922 if (length > IEEE80211_DATA_LEN) {
922 printk(KERN_WARNING "%s: Oversized frame received (%d bytes)\n", 923 printk(KERN_WARNING "%s: Oversized frame received (%d bytes)\n",
923 dev->name, length); 924 dev->name, length);
924 stats->rx_length_errors++; 925 stats->rx_length_errors++;
@@ -2272,7 +2273,7 @@ static int orinoco_init(struct net_device *dev)
2272 2273
2273 /* No need to lock, the hw_unavailable flag is already set in 2274 /* No need to lock, the hw_unavailable flag is already set in
2274 * alloc_orinocodev() */ 2275 * alloc_orinocodev() */
2275 priv->nicbuf_size = IEEE802_11_FRAME_LEN + ETH_HLEN; 2276 priv->nicbuf_size = IEEE80211_FRAME_LEN + ETH_HLEN;
2276 2277
2277 /* Initialize the firmware */ 2278 /* Initialize the firmware */
2278 err = orinoco_reinit_firmware(dev); 2279 err = orinoco_reinit_firmware(dev);
diff --git a/drivers/net/wireless/strip.c b/drivers/net/wireless/strip.c
index 6c42b573a95a..4b0acae22b0d 100644
--- a/drivers/net/wireless/strip.c
+++ b/drivers/net/wireless/strip.c
@@ -209,7 +209,7 @@ enum {
209 NoStructure = 0, /* Really old firmware */ 209 NoStructure = 0, /* Really old firmware */
210 StructuredMessages = 1, /* Parsable AT response msgs */ 210 StructuredMessages = 1, /* Parsable AT response msgs */
211 ChecksummedMessages = 2 /* Parsable AT response msgs with checksums */ 211 ChecksummedMessages = 2 /* Parsable AT response msgs with checksums */
212} FirmwareLevel; 212};
213 213
214struct strip { 214struct strip {
215 int magic; 215 int magic;
diff --git a/drivers/net/wireless/wavelan_cs.c b/drivers/net/wireless/wavelan_cs.c
index f6130a53b796..183c4732ef65 100644
--- a/drivers/net/wireless/wavelan_cs.c
+++ b/drivers/net/wireless/wavelan_cs.c
@@ -59,6 +59,12 @@
59/* Do *NOT* add other headers here, you are guaranteed to be wrong - Jean II */ 59/* Do *NOT* add other headers here, you are guaranteed to be wrong - Jean II */
60#include "wavelan_cs.p.h" /* Private header */ 60#include "wavelan_cs.p.h" /* Private header */
61 61
62#ifdef WAVELAN_ROAMING
63static void wl_cell_expiry(unsigned long data);
64static void wl_del_wavepoint(wavepoint_history *wavepoint, struct net_local *lp);
65static void wv_nwid_filter(unsigned char mode, net_local *lp);
66#endif /* WAVELAN_ROAMING */
67
62/************************* MISC SUBROUTINES **************************/ 68/************************* MISC SUBROUTINES **************************/
63/* 69/*
64 * Subroutines which won't fit in one of the following category 70 * Subroutines which won't fit in one of the following category
@@ -500,9 +506,9 @@ fee_write(u_long base, /* i/o port of the card */
500 506
501#ifdef WAVELAN_ROAMING /* Conditional compile, see wavelan_cs.h */ 507#ifdef WAVELAN_ROAMING /* Conditional compile, see wavelan_cs.h */
502 508
503unsigned char WAVELAN_BEACON_ADDRESS[]= {0x09,0x00,0x0e,0x20,0x03,0x00}; 509static unsigned char WAVELAN_BEACON_ADDRESS[] = {0x09,0x00,0x0e,0x20,0x03,0x00};
504 510
505void wv_roam_init(struct net_device *dev) 511static void wv_roam_init(struct net_device *dev)
506{ 512{
507 net_local *lp= netdev_priv(dev); 513 net_local *lp= netdev_priv(dev);
508 514
@@ -531,7 +537,7 @@ void wv_roam_init(struct net_device *dev)
531 printk(KERN_DEBUG "WaveLAN: Roaming enabled on device %s\n",dev->name); 537 printk(KERN_DEBUG "WaveLAN: Roaming enabled on device %s\n",dev->name);
532} 538}
533 539
534void wv_roam_cleanup(struct net_device *dev) 540static void wv_roam_cleanup(struct net_device *dev)
535{ 541{
536 wavepoint_history *ptr,*old_ptr; 542 wavepoint_history *ptr,*old_ptr;
537 net_local *lp= netdev_priv(dev); 543 net_local *lp= netdev_priv(dev);
@@ -550,7 +556,7 @@ void wv_roam_cleanup(struct net_device *dev)
550} 556}
551 557
552/* Enable/Disable NWID promiscuous mode on a given device */ 558/* Enable/Disable NWID promiscuous mode on a given device */
553void wv_nwid_filter(unsigned char mode, net_local *lp) 559static void wv_nwid_filter(unsigned char mode, net_local *lp)
554{ 560{
555 mm_t m; 561 mm_t m;
556 unsigned long flags; 562 unsigned long flags;
@@ -575,7 +581,7 @@ void wv_nwid_filter(unsigned char mode, net_local *lp)
575} 581}
576 582
577/* Find a record in the WavePoint table matching a given NWID */ 583/* Find a record in the WavePoint table matching a given NWID */
578wavepoint_history *wl_roam_check(unsigned short nwid, net_local *lp) 584static wavepoint_history *wl_roam_check(unsigned short nwid, net_local *lp)
579{ 585{
580 wavepoint_history *ptr=lp->wavepoint_table.head; 586 wavepoint_history *ptr=lp->wavepoint_table.head;
581 587
@@ -588,7 +594,7 @@ wavepoint_history *wl_roam_check(unsigned short nwid, net_local *lp)
588} 594}
589 595
590/* Create a new wavepoint table entry */ 596/* Create a new wavepoint table entry */
591wavepoint_history *wl_new_wavepoint(unsigned short nwid, unsigned char seq, net_local* lp) 597static wavepoint_history *wl_new_wavepoint(unsigned short nwid, unsigned char seq, net_local* lp)
592{ 598{
593 wavepoint_history *new_wavepoint; 599 wavepoint_history *new_wavepoint;
594 600
@@ -624,7 +630,7 @@ wavepoint_history *wl_new_wavepoint(unsigned short nwid, unsigned char seq, net_
624} 630}
625 631
626/* Remove a wavepoint entry from WavePoint table */ 632/* Remove a wavepoint entry from WavePoint table */
627void wl_del_wavepoint(wavepoint_history *wavepoint, struct net_local *lp) 633static void wl_del_wavepoint(wavepoint_history *wavepoint, struct net_local *lp)
628{ 634{
629 if(wavepoint==NULL) 635 if(wavepoint==NULL)
630 return; 636 return;
@@ -646,7 +652,7 @@ void wl_del_wavepoint(wavepoint_history *wavepoint, struct net_local *lp)
646} 652}
647 653
648/* Timer callback function - checks WavePoint table for stale entries */ 654/* Timer callback function - checks WavePoint table for stale entries */
649void wl_cell_expiry(unsigned long data) 655static void wl_cell_expiry(unsigned long data)
650{ 656{
651 net_local *lp=(net_local *)data; 657 net_local *lp=(net_local *)data;
652 wavepoint_history *wavepoint=lp->wavepoint_table.head,*old_point; 658 wavepoint_history *wavepoint=lp->wavepoint_table.head,*old_point;
@@ -686,7 +692,7 @@ void wl_cell_expiry(unsigned long data)
686} 692}
687 693
688/* Update SNR history of a wavepoint */ 694/* Update SNR history of a wavepoint */
689void wl_update_history(wavepoint_history *wavepoint, unsigned char sigqual, unsigned char seq) 695static void wl_update_history(wavepoint_history *wavepoint, unsigned char sigqual, unsigned char seq)
690{ 696{
691 int i=0,num_missed=0,ptr=0; 697 int i=0,num_missed=0,ptr=0;
692 int average_fast=0,average_slow=0; 698 int average_fast=0,average_slow=0;
@@ -723,7 +729,7 @@ void wl_update_history(wavepoint_history *wavepoint, unsigned char sigqual, unsi
723} 729}
724 730
725/* Perform a handover to a new WavePoint */ 731/* Perform a handover to a new WavePoint */
726void wv_roam_handover(wavepoint_history *wavepoint, net_local *lp) 732static void wv_roam_handover(wavepoint_history *wavepoint, net_local *lp)
727{ 733{
728 kio_addr_t base = lp->dev->base_addr; 734 kio_addr_t base = lp->dev->base_addr;
729 mm_t m; 735 mm_t m;
diff --git a/drivers/net/wireless/wavelan_cs.h b/drivers/net/wireless/wavelan_cs.h
index 29cff6daf860..fabc63ee153c 100644
--- a/drivers/net/wireless/wavelan_cs.h
+++ b/drivers/net/wireless/wavelan_cs.h
@@ -62,7 +62,7 @@
62 * like DEC RoamAbout, or Digital Ocean, Epson, ...), you must modify this 62 * like DEC RoamAbout, or Digital Ocean, Epson, ...), you must modify this
63 * part to accommodate your hardware... 63 * part to accommodate your hardware...
64 */ 64 */
65const unsigned char MAC_ADDRESSES[][3] = 65static const unsigned char MAC_ADDRESSES[][3] =
66{ 66{
67 { 0x08, 0x00, 0x0E }, /* AT&T Wavelan (standard) & DEC RoamAbout */ 67 { 0x08, 0x00, 0x0E }, /* AT&T Wavelan (standard) & DEC RoamAbout */
68 { 0x08, 0x00, 0x6A }, /* AT&T Wavelan (alternate) */ 68 { 0x08, 0x00, 0x6A }, /* AT&T Wavelan (alternate) */
@@ -79,14 +79,14 @@ const unsigned char MAC_ADDRESSES[][3] =
79 * (as read in the offset register of the dac area). 79 * (as read in the offset register of the dac area).
80 * Used to map channel numbers used by `wfreqsel' to frequencies 80 * Used to map channel numbers used by `wfreqsel' to frequencies
81 */ 81 */
82const short channel_bands[] = { 0x30, 0x58, 0x64, 0x7A, 0x80, 0xA8, 82static const short channel_bands[] = { 0x30, 0x58, 0x64, 0x7A, 0x80, 0xA8,
83 0xD0, 0xF0, 0xF8, 0x150 }; 83 0xD0, 0xF0, 0xF8, 0x150 };
84 84
85/* Frequencies of the 1.0 modem (fixed frequencies). 85/* Frequencies of the 1.0 modem (fixed frequencies).
86 * Use to map the PSA `subband' to a frequency 86 * Use to map the PSA `subband' to a frequency
87 * Note : all frequencies apart from the first one need to be multiplied by 10 87 * Note : all frequencies apart from the first one need to be multiplied by 10
88 */ 88 */
89const int fixed_bands[] = { 915e6, 2.425e8, 2.46e8, 2.484e8, 2.4305e8 }; 89static const int fixed_bands[] = { 915e6, 2.425e8, 2.46e8, 2.484e8, 2.4305e8 };
90 90
91 91
92/*************************** PC INTERFACE ****************************/ 92/*************************** PC INTERFACE ****************************/
diff --git a/drivers/net/wireless/wavelan_cs.p.h b/drivers/net/wireless/wavelan_cs.p.h
index 677ff71883cb..01d882be8790 100644
--- a/drivers/net/wireless/wavelan_cs.p.h
+++ b/drivers/net/wireless/wavelan_cs.p.h
@@ -647,23 +647,6 @@ struct net_local
647 void __iomem *mem; 647 void __iomem *mem;
648}; 648};
649 649
650/**************************** PROTOTYPES ****************************/
651
652#ifdef WAVELAN_ROAMING
653/* ---------------------- ROAMING SUBROUTINES -----------------------*/
654
655wavepoint_history *wl_roam_check(unsigned short nwid, net_local *lp);
656wavepoint_history *wl_new_wavepoint(unsigned short nwid, unsigned char seq, net_local *lp);
657void wl_del_wavepoint(wavepoint_history *wavepoint, net_local *lp);
658void wl_cell_expiry(unsigned long data);
659wavepoint_history *wl_best_sigqual(int fast_search, net_local *lp);
660void wl_update_history(wavepoint_history *wavepoint, unsigned char sigqual, unsigned char seq);
661void wv_roam_handover(wavepoint_history *wavepoint, net_local *lp);
662void wv_nwid_filter(unsigned char mode, net_local *lp);
663void wv_roam_init(struct net_device *dev);
664void wv_roam_cleanup(struct net_device *dev);
665#endif /* WAVELAN_ROAMING */
666
667/* ----------------- MODEM MANAGEMENT SUBROUTINES ----------------- */ 650/* ----------------- MODEM MANAGEMENT SUBROUTINES ----------------- */
668static inline u_char /* data */ 651static inline u_char /* data */
669 hasr_read(u_long); /* Read the host interface : base address */ 652 hasr_read(u_long); /* Read the host interface : base address */
diff --git a/drivers/net/wireless/wl3501.h b/drivers/net/wireless/wl3501.h
index 8636d9306785..b5719437e981 100644
--- a/drivers/net/wireless/wl3501.h
+++ b/drivers/net/wireless/wl3501.h
@@ -2,7 +2,7 @@
2#define __WL3501_H__ 2#define __WL3501_H__
3 3
4#include <linux/spinlock.h> 4#include <linux/spinlock.h>
5#include "ieee802_11.h" 5#include <net/ieee80211.h>
6 6
7/* define for WLA 2.0 */ 7/* define for WLA 2.0 */
8#define WL3501_BLKSZ 256 8#define WL3501_BLKSZ 256
@@ -548,7 +548,7 @@ struct wl3501_80211_tx_plcp_hdr {
548 548
549struct wl3501_80211_tx_hdr { 549struct wl3501_80211_tx_hdr {
550 struct wl3501_80211_tx_plcp_hdr pclp_hdr; 550 struct wl3501_80211_tx_plcp_hdr pclp_hdr;
551 struct ieee802_11_hdr mac_hdr; 551 struct ieee80211_hdr mac_hdr;
552} __attribute__ ((packed)); 552} __attribute__ ((packed));
553 553
554/* 554/*
diff --git a/drivers/net/wireless/wl3501_cs.c b/drivers/net/wireless/wl3501_cs.c
index dd902126d018..7cc5edbf6ede 100644
--- a/drivers/net/wireless/wl3501_cs.c
+++ b/drivers/net/wireless/wl3501_cs.c
@@ -296,7 +296,8 @@ static int wl3501_get_flash_mac_addr(struct wl3501_card *this)
296 * 296 *
297 * Move 'size' bytes from PC to card. (Shouldn't be interrupted) 297 * Move 'size' bytes from PC to card. (Shouldn't be interrupted)
298 */ 298 */
299void wl3501_set_to_wla(struct wl3501_card *this, u16 dest, void *src, int size) 299static void wl3501_set_to_wla(struct wl3501_card *this, u16 dest, void *src,
300 int size)
300{ 301{
301 /* switch to SRAM Page 0 */ 302 /* switch to SRAM Page 0 */
302 wl3501_switch_page(this, (dest & 0x8000) ? WL3501_BSS_SPAGE1 : 303 wl3501_switch_page(this, (dest & 0x8000) ? WL3501_BSS_SPAGE1 :
@@ -317,8 +318,8 @@ void wl3501_set_to_wla(struct wl3501_card *this, u16 dest, void *src, int size)
317 * 318 *
318 * Move 'size' bytes from card to PC. (Shouldn't be interrupted) 319 * Move 'size' bytes from card to PC. (Shouldn't be interrupted)
319 */ 320 */
320void wl3501_get_from_wla(struct wl3501_card *this, u16 src, void *dest, 321static void wl3501_get_from_wla(struct wl3501_card *this, u16 src, void *dest,
321 int size) 322 int size)
322{ 323{
323 /* switch to SRAM Page 0 */ 324 /* switch to SRAM Page 0 */
324 wl3501_switch_page(this, (src & 0x8000) ? WL3501_BSS_SPAGE1 : 325 wl3501_switch_page(this, (src & 0x8000) ? WL3501_BSS_SPAGE1 :
@@ -1438,14 +1439,14 @@ fail:
1438 goto out; 1439 goto out;
1439} 1440}
1440 1441
1441struct net_device_stats *wl3501_get_stats(struct net_device *dev) 1442static struct net_device_stats *wl3501_get_stats(struct net_device *dev)
1442{ 1443{
1443 struct wl3501_card *this = dev->priv; 1444 struct wl3501_card *this = dev->priv;
1444 1445
1445 return &this->stats; 1446 return &this->stats;
1446} 1447}
1447 1448
1448struct iw_statistics *wl3501_get_wireless_stats(struct net_device *dev) 1449static struct iw_statistics *wl3501_get_wireless_stats(struct net_device *dev)
1449{ 1450{
1450 struct wl3501_card *this = dev->priv; 1451 struct wl3501_card *this = dev->priv;
1451 struct iw_statistics *wstats = &this->wstats; 1452 struct iw_statistics *wstats = &this->wstats;
diff --git a/drivers/pci/rom.c b/drivers/pci/rom.c
index 713c78f3a65d..49bd21702314 100644
--- a/drivers/pci/rom.c
+++ b/drivers/pci/rom.c
@@ -21,13 +21,21 @@
21 * between the ROM and other resources, so enabling it may disable access 21 * between the ROM and other resources, so enabling it may disable access
22 * to MMIO registers or other card memory. 22 * to MMIO registers or other card memory.
23 */ 23 */
24static void pci_enable_rom(struct pci_dev *pdev) 24static int pci_enable_rom(struct pci_dev *pdev)
25{ 25{
26 struct resource *res = pdev->resource + PCI_ROM_RESOURCE;
27 struct pci_bus_region region;
26 u32 rom_addr; 28 u32 rom_addr;
27 29
30 if (!res->flags)
31 return -1;
32
33 pcibios_resource_to_bus(pdev, &region, res);
28 pci_read_config_dword(pdev, pdev->rom_base_reg, &rom_addr); 34 pci_read_config_dword(pdev, pdev->rom_base_reg, &rom_addr);
29 rom_addr |= PCI_ROM_ADDRESS_ENABLE; 35 rom_addr &= ~PCI_ROM_ADDRESS_MASK;
36 rom_addr |= region.start | PCI_ROM_ADDRESS_ENABLE;
30 pci_write_config_dword(pdev, pdev->rom_base_reg, rom_addr); 37 pci_write_config_dword(pdev, pdev->rom_base_reg, rom_addr);
38 return 0;
31} 39}
32 40
33/** 41/**
@@ -71,19 +79,21 @@ void __iomem *pci_map_rom(struct pci_dev *pdev, size_t *size)
71 } else { 79 } else {
72 if (res->flags & IORESOURCE_ROM_COPY) { 80 if (res->flags & IORESOURCE_ROM_COPY) {
73 *size = pci_resource_len(pdev, PCI_ROM_RESOURCE); 81 *size = pci_resource_len(pdev, PCI_ROM_RESOURCE);
74 return (void __iomem *)pci_resource_start(pdev, PCI_ROM_RESOURCE); 82 return (void __iomem *)pci_resource_start(pdev,
83 PCI_ROM_RESOURCE);
75 } else { 84 } else {
76 /* assign the ROM an address if it doesn't have one */ 85 /* assign the ROM an address if it doesn't have one */
77 if (res->parent == NULL) 86 if (res->parent == NULL &&
78 pci_assign_resource(pdev, PCI_ROM_RESOURCE); 87 pci_assign_resource(pdev,PCI_ROM_RESOURCE))
79 88 return NULL;
80 start = pci_resource_start(pdev, PCI_ROM_RESOURCE); 89 start = pci_resource_start(pdev, PCI_ROM_RESOURCE);
81 *size = pci_resource_len(pdev, PCI_ROM_RESOURCE); 90 *size = pci_resource_len(pdev, PCI_ROM_RESOURCE);
82 if (*size == 0) 91 if (*size == 0)
83 return NULL; 92 return NULL;
84 93
85 /* Enable ROM space decodes */ 94 /* Enable ROM space decodes */
86 pci_enable_rom(pdev); 95 if (pci_enable_rom(pdev))
96 return NULL;
87 } 97 }
88 } 98 }
89 99
diff --git a/drivers/pci/setup-bus.c b/drivers/pci/setup-bus.c
index 6d864c502a1f..6b0e6464eb39 100644
--- a/drivers/pci/setup-bus.c
+++ b/drivers/pci/setup-bus.c
@@ -40,7 +40,7 @@
40 * FIXME: IO should be max 256 bytes. However, since we may 40 * FIXME: IO should be max 256 bytes. However, since we may
41 * have a P2P bridge below a cardbus bridge, we need 4K. 41 * have a P2P bridge below a cardbus bridge, we need 4K.
42 */ 42 */
43#define CARDBUS_IO_SIZE (256) 43#define CARDBUS_IO_SIZE (4*1024)
44#define CARDBUS_MEM_SIZE (32*1024*1024) 44#define CARDBUS_MEM_SIZE (32*1024*1024)
45 45
46static void __devinit 46static void __devinit
diff --git a/drivers/scsi/ahci.c b/drivers/scsi/ahci.c
index 841f4e2cfe08..179c95c878ac 100644
--- a/drivers/scsi/ahci.c
+++ b/drivers/scsi/ahci.c
@@ -1,26 +1,34 @@
1/* 1/*
2 * ahci.c - AHCI SATA support 2 * ahci.c - AHCI SATA support
3 * 3 *
4 * Copyright 2004 Red Hat, Inc. 4 * Maintained by: Jeff Garzik <jgarzik@pobox.com>
5 * Please ALWAYS copy linux-ide@vger.kernel.org
6 * on emails.
5 * 7 *
6 * The contents of this file are subject to the Open 8 * Copyright 2004-2005 Red Hat, Inc.
7 * Software License version 1.1 that can be found at
8 * http://www.opensource.org/licenses/osl-1.1.txt and is included herein
9 * by reference.
10 * 9 *
11 * Alternatively, the contents of this file may be used under the terms
12 * of the GNU General Public License version 2 (the "GPL") as distributed
13 * in the kernel source COPYING file, in which case the provisions of
14 * the GPL are applicable instead of the above. If you wish to allow
15 * the use of your version of this file only under the terms of the
16 * GPL and not to allow others to use your version of this file under
17 * the OSL, indicate your decision by deleting the provisions above and
18 * replace them with the notice and other provisions required by the GPL.
19 * If you do not delete the provisions above, a recipient may use your
20 * version of this file under either the OSL or the GPL.
21 * 10 *
22 * Version 1.0 of the AHCI specification: 11 * This program is free software; you can redistribute it and/or modify
12 * it under the terms of the GNU General Public License as published by
13 * the Free Software Foundation; either version 2, or (at your option)
14 * any later version.
15 *
16 * This program is distributed in the hope that it will be useful,
17 * but WITHOUT ANY WARRANTY; without even the implied warranty of
18 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 * GNU General Public License for more details.
20 *
21 * You should have received a copy of the GNU General Public License
22 * along with this program; see the file COPYING. If not, write to
23 * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
24 *
25 *
26 * libata documentation is available via 'make {ps|pdf}docs',
27 * as Documentation/DocBook/libata.*
28 *
29 * AHCI hardware documentation:
23 * http://www.intel.com/technology/serialata/pdf/rev1_0.pdf 30 * http://www.intel.com/technology/serialata/pdf/rev1_0.pdf
31 * http://www.intel.com/technology/serialata/pdf/rev1_1.pdf
24 * 32 *
25 */ 33 */
26 34
diff --git a/drivers/scsi/ata_piix.c b/drivers/scsi/ata_piix.c
index 03695616e59e..fb28c1261848 100644
--- a/drivers/scsi/ata_piix.c
+++ b/drivers/scsi/ata_piix.c
@@ -1,24 +1,42 @@
1/* 1/*
2 2 * ata_piix.c - Intel PATA/SATA controllers
3 ata_piix.c - Intel PATA/SATA controllers 3 *
4 4 * Maintained by: Jeff Garzik <jgarzik@pobox.com>
5 Maintained by: Jeff Garzik <jgarzik@pobox.com> 5 * Please ALWAYS copy linux-ide@vger.kernel.org
6 Please ALWAYS copy linux-ide@vger.kernel.org 6 * on emails.
7 on emails. 7 *
8 8 *
9 9 * Copyright 2003-2005 Red Hat Inc
10 Copyright 2003-2004 Red Hat Inc 10 * Copyright 2003-2005 Jeff Garzik
11 Copyright 2003-2004 Jeff Garzik 11 *
12 12 *
13 13 * Copyright header from piix.c:
14 Copyright header from piix.c: 14 *
15 15 * Copyright (C) 1998-1999 Andrzej Krzysztofowicz, Author and Maintainer
16 Copyright (C) 1998-1999 Andrzej Krzysztofowicz, Author and Maintainer 16 * Copyright (C) 1998-2000 Andre Hedrick <andre@linux-ide.org>
17 Copyright (C) 1998-2000 Andre Hedrick <andre@linux-ide.org> 17 * Copyright (C) 2003 Red Hat Inc <alan@redhat.com>
18 Copyright (C) 2003 Red Hat Inc <alan@redhat.com> 18 *
19 19 *
20 May be copied or modified under the terms of the GNU General Public License 20 * This program is free software; you can redistribute it and/or modify
21 21 * it under the terms of the GNU General Public License as published by
22 * the Free Software Foundation; either version 2, or (at your option)
23 * any later version.
24 *
25 * This program is distributed in the hope that it will be useful,
26 * but WITHOUT ANY WARRANTY; without even the implied warranty of
27 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
28 * GNU General Public License for more details.
29 *
30 * You should have received a copy of the GNU General Public License
31 * along with this program; see the file COPYING. If not, write to
32 * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
33 *
34 *
35 * libata documentation is available via 'make {ps|pdf}docs',
36 * as Documentation/DocBook/libata.*
37 *
38 * Hardware documentation available at http://developer.intel.com/
39 *
22 */ 40 */
23 41
24#include <linux/kernel.h> 42#include <linux/kernel.h>
diff --git a/drivers/scsi/ibmvscsi/ibmvscsi.c b/drivers/scsi/ibmvscsi/ibmvscsi.c
index fe09d145542a..2cb3c8340ca8 100644
--- a/drivers/scsi/ibmvscsi/ibmvscsi.c
+++ b/drivers/scsi/ibmvscsi/ibmvscsi.c
@@ -1442,7 +1442,7 @@ static int ibmvscsi_remove(struct vio_dev *vdev)
1442 */ 1442 */
1443static struct vio_device_id ibmvscsi_device_table[] __devinitdata = { 1443static struct vio_device_id ibmvscsi_device_table[] __devinitdata = {
1444 {"vscsi", "IBM,v-scsi"}, 1444 {"vscsi", "IBM,v-scsi"},
1445 {0,} 1445 { "", "" }
1446}; 1446};
1447 1447
1448MODULE_DEVICE_TABLE(vio, ibmvscsi_device_table); 1448MODULE_DEVICE_TABLE(vio, ibmvscsi_device_table);
diff --git a/drivers/scsi/ibmvscsi/rpa_vscsi.c b/drivers/scsi/ibmvscsi/rpa_vscsi.c
index 035f615817d7..8bf5652f1060 100644
--- a/drivers/scsi/ibmvscsi/rpa_vscsi.c
+++ b/drivers/scsi/ibmvscsi/rpa_vscsi.c
@@ -28,6 +28,7 @@
28 */ 28 */
29 29
30#include <asm/vio.h> 30#include <asm/vio.h>
31#include <asm/prom.h>
31#include <asm/iommu.h> 32#include <asm/iommu.h>
32#include <asm/hvcall.h> 33#include <asm/hvcall.h>
33#include <linux/dma-mapping.h> 34#include <linux/dma-mapping.h>
diff --git a/drivers/scsi/libata-core.c b/drivers/scsi/libata-core.c
index f15a07f9f471..dee4b12b0342 100644
--- a/drivers/scsi/libata-core.c
+++ b/drivers/scsi/libata-core.c
@@ -1,25 +1,35 @@
1/* 1/*
2 libata-core.c - helper library for ATA 2 * libata-core.c - helper library for ATA
3 3 *
4 Copyright 2003-2004 Red Hat, Inc. All rights reserved. 4 * Maintained by: Jeff Garzik <jgarzik@pobox.com>
5 Copyright 2003-2004 Jeff Garzik 5 * Please ALWAYS copy linux-ide@vger.kernel.org
6 6 * on emails.
7 The contents of this file are subject to the Open 7 *
8 Software License version 1.1 that can be found at 8 * Copyright 2003-2004 Red Hat, Inc. All rights reserved.
9 http://www.opensource.org/licenses/osl-1.1.txt and is included herein 9 * Copyright 2003-2004 Jeff Garzik
10 by reference. 10 *
11 11 *
12 Alternatively, the contents of this file may be used under the terms 12 * This program is free software; you can redistribute it and/or modify
13 of the GNU General Public License version 2 (the "GPL") as distributed 13 * it under the terms of the GNU General Public License as published by
14 in the kernel source COPYING file, in which case the provisions of 14 * the Free Software Foundation; either version 2, or (at your option)
15 the GPL are applicable instead of the above. If you wish to allow 15 * any later version.
16 the use of your version of this file only under the terms of the 16 *
17 GPL and not to allow others to use your version of this file under 17 * This program is distributed in the hope that it will be useful,
18 the OSL, indicate your decision by deleting the provisions above and 18 * but WITHOUT ANY WARRANTY; without even the implied warranty of
19 replace them with the notice and other provisions required by the GPL. 19 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
20 If you do not delete the provisions above, a recipient may use your 20 * GNU General Public License for more details.
21 version of this file under either the OSL or the GPL. 21 *
22 22 * You should have received a copy of the GNU General Public License
23 * along with this program; see the file COPYING. If not, write to
24 * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
25 *
26 *
27 * libata documentation is available via 'make {ps|pdf}docs',
28 * as Documentation/DocBook/libata.*
29 *
30 * Hardware documentation available from http://www.t13.org/ and
31 * http://www.sata-io.org/
32 *
23 */ 33 */
24 34
25#include <linux/config.h> 35#include <linux/config.h>
diff --git a/drivers/scsi/libata-scsi.c b/drivers/scsi/libata-scsi.c
index 4074e7877ba3..346eb36b1e31 100644
--- a/drivers/scsi/libata-scsi.c
+++ b/drivers/scsi/libata-scsi.c
@@ -1,25 +1,36 @@
1/* 1/*
2 libata-scsi.c - helper library for ATA 2 * libata-scsi.c - helper library for ATA
3 3 *
4 Copyright 2003-2004 Red Hat, Inc. All rights reserved. 4 * Maintained by: Jeff Garzik <jgarzik@pobox.com>
5 Copyright 2003-2004 Jeff Garzik 5 * Please ALWAYS copy linux-ide@vger.kernel.org
6 6 * on emails.
7 The contents of this file are subject to the Open 7 *
8 Software License version 1.1 that can be found at 8 * Copyright 2003-2004 Red Hat, Inc. All rights reserved.
9 http://www.opensource.org/licenses/osl-1.1.txt and is included herein 9 * Copyright 2003-2004 Jeff Garzik
10 by reference. 10 *
11 11 *
12 Alternatively, the contents of this file may be used under the terms 12 * This program is free software; you can redistribute it and/or modify
13 of the GNU General Public License version 2 (the "GPL") as distributed 13 * it under the terms of the GNU General Public License as published by
14 in the kernel source COPYING file, in which case the provisions of 14 * the Free Software Foundation; either version 2, or (at your option)
15 the GPL are applicable instead of the above. If you wish to allow 15 * any later version.
16 the use of your version of this file only under the terms of the 16 *
17 GPL and not to allow others to use your version of this file under 17 * This program is distributed in the hope that it will be useful,
18 the OSL, indicate your decision by deleting the provisions above and 18 * but WITHOUT ANY WARRANTY; without even the implied warranty of
19 replace them with the notice and other provisions required by the GPL. 19 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
20 If you do not delete the provisions above, a recipient may use your 20 * GNU General Public License for more details.
21 version of this file under either the OSL or the GPL. 21 *
22 22 * You should have received a copy of the GNU General Public License
23 * along with this program; see the file COPYING. If not, write to
24 * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
25 *
26 *
27 * libata documentation is available via 'make {ps|pdf}docs',
28 * as Documentation/DocBook/libata.*
29 *
30 * Hardware documentation available from
31 * - http://www.t10.org/
32 * - http://www.t13.org/
33 *
23 */ 34 */
24 35
25#include <linux/kernel.h> 36#include <linux/kernel.h>
diff --git a/drivers/scsi/libata.h b/drivers/scsi/libata.h
index 620d21772bd6..809c634afbcd 100644
--- a/drivers/scsi/libata.h
+++ b/drivers/scsi/libata.h
@@ -1,25 +1,28 @@
1/* 1/*
2 libata.h - helper library for ATA 2 * libata.h - helper library for ATA
3 3 *
4 Copyright 2003-2004 Red Hat, Inc. All rights reserved. 4 * Copyright 2003-2004 Red Hat, Inc. All rights reserved.
5 Copyright 2003-2004 Jeff Garzik 5 * Copyright 2003-2004 Jeff Garzik
6 6 *
7 The contents of this file are subject to the Open 7 *
8 Software License version 1.1 that can be found at 8 * This program is free software; you can redistribute it and/or modify
9 http://www.opensource.org/licenses/osl-1.1.txt and is included herein 9 * it under the terms of the GNU General Public License as published by
10 by reference. 10 * the Free Software Foundation; either version 2, or (at your option)
11 11 * any later version.
12 Alternatively, the contents of this file may be used under the terms 12 *
13 of the GNU General Public License version 2 (the "GPL") as distributed 13 * This program is distributed in the hope that it will be useful,
14 in the kernel source COPYING file, in which case the provisions of 14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 the GPL are applicable instead of the above. If you wish to allow 15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 the use of your version of this file only under the terms of the 16 * GNU General Public License for more details.
17 GPL and not to allow others to use your version of this file under 17 *
18 the OSL, indicate your decision by deleting the provisions above and 18 * You should have received a copy of the GNU General Public License
19 replace them with the notice and other provisions required by the GPL. 19 * along with this program; see the file COPYING. If not, write to
20 If you do not delete the provisions above, a recipient may use your 20 * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
21 version of this file under either the OSL or the GPL. 21 *
22 22 *
23 * libata documentation is available via 'make {ps|pdf}docs',
24 * as Documentation/DocBook/libata.*
25 *
23 */ 26 */
24 27
25#ifndef __LIBATA_H__ 28#ifndef __LIBATA_H__
diff --git a/drivers/scsi/sata_nv.c b/drivers/scsi/sata_nv.c
index 41a3421b02b4..03d9bc6e69df 100644
--- a/drivers/scsi/sata_nv.c
+++ b/drivers/scsi/sata_nv.c
@@ -4,21 +4,31 @@
4 * Copyright 2004 NVIDIA Corp. All rights reserved. 4 * Copyright 2004 NVIDIA Corp. All rights reserved.
5 * Copyright 2004 Andrew Chew 5 * Copyright 2004 Andrew Chew
6 * 6 *
7 * The contents of this file are subject to the Open
8 * Software License version 1.1 that can be found at
9 * http://www.opensource.org/licenses/osl-1.1.txt and is included herein
10 * by reference.
11 * 7 *
12 * Alternatively, the contents of this file may be used under the terms 8 * This program is free software; you can redistribute it and/or modify
13 * of the GNU General Public License version 2 (the "GPL") as distributed 9 * it under the terms of the GNU General Public License as published by
14 * in the kernel source COPYING file, in which case the provisions of 10 * the Free Software Foundation; either version 2, or (at your option)
15 * the GPL are applicable instead of the above. If you wish to allow 11 * any later version.
16 * the use of your version of this file only under the terms of the 12 *
17 * GPL and not to allow others to use your version of this file under 13 * This program is distributed in the hope that it will be useful,
18 * the OSL, indicate your decision by deleting the provisions above and 14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
19 * replace them with the notice and other provisions required by the GPL. 15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
20 * If you do not delete the provisions above, a recipient may use your 16 * GNU General Public License for more details.
21 * version of this file under either the OSL or the GPL. 17 *
18 * You should have received a copy of the GNU General Public License
19 * along with this program; see the file COPYING. If not, write to
20 * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
21 *
22 *
23 * libata documentation is available via 'make {ps|pdf}docs',
24 * as Documentation/DocBook/libata.*
25 *
26 * No hardware documentation available outside of NVIDIA.
27 * This driver programs the NVIDIA SATA controller in a similar
28 * fashion as with other PCI IDE BMDMA controllers, with a few
29 * NV-specific details such as register offsets, SATA phy location,
30 * hotplug info, etc.
31 *
22 * 32 *
23 * 0.08 33 * 0.08
24 * - Added support for MCP51 and MCP55. 34 * - Added support for MCP51 and MCP55.
diff --git a/drivers/scsi/sata_promise.c b/drivers/scsi/sata_promise.c
index b8dc49fed769..7c4f6ecc1cc9 100644
--- a/drivers/scsi/sata_promise.c
+++ b/drivers/scsi/sata_promise.c
@@ -7,21 +7,26 @@
7 * 7 *
8 * Copyright 2003-2004 Red Hat, Inc. 8 * Copyright 2003-2004 Red Hat, Inc.
9 * 9 *
10 * The contents of this file are subject to the Open
11 * Software License version 1.1 that can be found at
12 * http://www.opensource.org/licenses/osl-1.1.txt and is included herein
13 * by reference.
14 * 10 *
15 * Alternatively, the contents of this file may be used under the terms 11 * This program is free software; you can redistribute it and/or modify
16 * of the GNU General Public License version 2 (the "GPL") as distributed 12 * it under the terms of the GNU General Public License as published by
17 * in the kernel source COPYING file, in which case the provisions of 13 * the Free Software Foundation; either version 2, or (at your option)
18 * the GPL are applicable instead of the above. If you wish to allow 14 * any later version.
19 * the use of your version of this file only under the terms of the 15 *
20 * GPL and not to allow others to use your version of this file under 16 * This program is distributed in the hope that it will be useful,
21 * the OSL, indicate your decision by deleting the provisions above and 17 * but WITHOUT ANY WARRANTY; without even the implied warranty of
22 * replace them with the notice and other provisions required by the GPL. 18 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
23 * If you do not delete the provisions above, a recipient may use your 19 * GNU General Public License for more details.
24 * version of this file under either the OSL or the GPL. 20 *
21 * You should have received a copy of the GNU General Public License
22 * along with this program; see the file COPYING. If not, write to
23 * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
24 *
25 *
26 * libata documentation is available via 'make {ps|pdf}docs',
27 * as Documentation/DocBook/libata.*
28 *
29 * Hardware information only available under NDA.
25 * 30 *
26 */ 31 */
27 32
@@ -79,7 +84,8 @@ static irqreturn_t pdc_interrupt (int irq, void *dev_instance, struct pt_regs *r
79static void pdc_eng_timeout(struct ata_port *ap); 84static void pdc_eng_timeout(struct ata_port *ap);
80static int pdc_port_start(struct ata_port *ap); 85static int pdc_port_start(struct ata_port *ap);
81static void pdc_port_stop(struct ata_port *ap); 86static void pdc_port_stop(struct ata_port *ap);
82static void pdc_phy_reset(struct ata_port *ap); 87static void pdc_pata_phy_reset(struct ata_port *ap);
88static void pdc_sata_phy_reset(struct ata_port *ap);
83static void pdc_qc_prep(struct ata_queued_cmd *qc); 89static void pdc_qc_prep(struct ata_queued_cmd *qc);
84static void pdc_tf_load_mmio(struct ata_port *ap, struct ata_taskfile *tf); 90static void pdc_tf_load_mmio(struct ata_port *ap, struct ata_taskfile *tf);
85static void pdc_exec_command_mmio(struct ata_port *ap, struct ata_taskfile *tf); 91static void pdc_exec_command_mmio(struct ata_port *ap, struct ata_taskfile *tf);
@@ -106,19 +112,22 @@ static Scsi_Host_Template pdc_ata_sht = {
106 .ordered_flush = 1, 112 .ordered_flush = 1,
107}; 113};
108 114
109static struct ata_port_operations pdc_ata_ops = { 115static struct ata_port_operations pdc_sata_ops = {
110 .port_disable = ata_port_disable, 116 .port_disable = ata_port_disable,
111 .tf_load = pdc_tf_load_mmio, 117 .tf_load = pdc_tf_load_mmio,
112 .tf_read = ata_tf_read, 118 .tf_read = ata_tf_read,
113 .check_status = ata_check_status, 119 .check_status = ata_check_status,
114 .exec_command = pdc_exec_command_mmio, 120 .exec_command = pdc_exec_command_mmio,
115 .dev_select = ata_std_dev_select, 121 .dev_select = ata_std_dev_select,
116 .phy_reset = pdc_phy_reset, 122
123 .phy_reset = pdc_sata_phy_reset,
124
117 .qc_prep = pdc_qc_prep, 125 .qc_prep = pdc_qc_prep,
118 .qc_issue = pdc_qc_issue_prot, 126 .qc_issue = pdc_qc_issue_prot,
119 .eng_timeout = pdc_eng_timeout, 127 .eng_timeout = pdc_eng_timeout,
120 .irq_handler = pdc_interrupt, 128 .irq_handler = pdc_interrupt,
121 .irq_clear = pdc_irq_clear, 129 .irq_clear = pdc_irq_clear,
130
122 .scr_read = pdc_sata_scr_read, 131 .scr_read = pdc_sata_scr_read,
123 .scr_write = pdc_sata_scr_write, 132 .scr_write = pdc_sata_scr_write,
124 .port_start = pdc_port_start, 133 .port_start = pdc_port_start,
@@ -126,6 +135,27 @@ static struct ata_port_operations pdc_ata_ops = {
126 .host_stop = ata_host_stop, 135 .host_stop = ata_host_stop,
127}; 136};
128 137
138static struct ata_port_operations pdc_pata_ops = {
139 .port_disable = ata_port_disable,
140 .tf_load = pdc_tf_load_mmio,
141 .tf_read = ata_tf_read,
142 .check_status = ata_check_status,
143 .exec_command = pdc_exec_command_mmio,
144 .dev_select = ata_std_dev_select,
145
146 .phy_reset = pdc_pata_phy_reset,
147
148 .qc_prep = pdc_qc_prep,
149 .qc_issue = pdc_qc_issue_prot,
150 .eng_timeout = pdc_eng_timeout,
151 .irq_handler = pdc_interrupt,
152 .irq_clear = pdc_irq_clear,
153
154 .port_start = pdc_port_start,
155 .port_stop = pdc_port_stop,
156 .host_stop = ata_host_stop,
157};
158
129static struct ata_port_info pdc_port_info[] = { 159static struct ata_port_info pdc_port_info[] = {
130 /* board_2037x */ 160 /* board_2037x */
131 { 161 {
@@ -135,7 +165,7 @@ static struct ata_port_info pdc_port_info[] = {
135 .pio_mask = 0x1f, /* pio0-4 */ 165 .pio_mask = 0x1f, /* pio0-4 */
136 .mwdma_mask = 0x07, /* mwdma0-2 */ 166 .mwdma_mask = 0x07, /* mwdma0-2 */
137 .udma_mask = 0x7f, /* udma0-6 ; FIXME */ 167 .udma_mask = 0x7f, /* udma0-6 ; FIXME */
138 .port_ops = &pdc_ata_ops, 168 .port_ops = &pdc_sata_ops,
139 }, 169 },
140 170
141 /* board_20319 */ 171 /* board_20319 */
@@ -146,7 +176,7 @@ static struct ata_port_info pdc_port_info[] = {
146 .pio_mask = 0x1f, /* pio0-4 */ 176 .pio_mask = 0x1f, /* pio0-4 */
147 .mwdma_mask = 0x07, /* mwdma0-2 */ 177 .mwdma_mask = 0x07, /* mwdma0-2 */
148 .udma_mask = 0x7f, /* udma0-6 ; FIXME */ 178 .udma_mask = 0x7f, /* udma0-6 ; FIXME */
149 .port_ops = &pdc_ata_ops, 179 .port_ops = &pdc_sata_ops,
150 }, 180 },
151 181
152 /* board_20619 */ 182 /* board_20619 */
@@ -157,7 +187,7 @@ static struct ata_port_info pdc_port_info[] = {
157 .pio_mask = 0x1f, /* pio0-4 */ 187 .pio_mask = 0x1f, /* pio0-4 */
158 .mwdma_mask = 0x07, /* mwdma0-2 */ 188 .mwdma_mask = 0x07, /* mwdma0-2 */
159 .udma_mask = 0x7f, /* udma0-6 ; FIXME */ 189 .udma_mask = 0x7f, /* udma0-6 ; FIXME */
160 .port_ops = &pdc_ata_ops, 190 .port_ops = &pdc_pata_ops,
161 }, 191 },
162}; 192};
163 193
@@ -272,12 +302,23 @@ static void pdc_reset_port(struct ata_port *ap)
272 readl(mmio); /* flush */ 302 readl(mmio); /* flush */
273} 303}
274 304
275static void pdc_phy_reset(struct ata_port *ap) 305static void pdc_sata_phy_reset(struct ata_port *ap)
276{ 306{
277 pdc_reset_port(ap); 307 pdc_reset_port(ap);
278 sata_phy_reset(ap); 308 sata_phy_reset(ap);
279} 309}
280 310
311static void pdc_pata_phy_reset(struct ata_port *ap)
312{
313 /* FIXME: add cable detect. Don't assume 40-pin cable */
314 ap->cbl = ATA_CBL_PATA40;
315 ap->udma_mask &= ATA_UDMA_MASK_40C;
316
317 pdc_reset_port(ap);
318 ata_port_probe(ap);
319 ata_bus_reset(ap);
320}
321
281static u32 pdc_sata_scr_read (struct ata_port *ap, unsigned int sc_reg) 322static u32 pdc_sata_scr_read (struct ata_port *ap, unsigned int sc_reg)
282{ 323{
283 if (sc_reg > SCR_CONTROL) 324 if (sc_reg > SCR_CONTROL)
diff --git a/drivers/scsi/sata_promise.h b/drivers/scsi/sata_promise.h
index 6e7e96b9ee13..6ee5e190262d 100644
--- a/drivers/scsi/sata_promise.h
+++ b/drivers/scsi/sata_promise.h
@@ -3,21 +3,24 @@
3 * 3 *
4 * Copyright 2003-2004 Red Hat, Inc. 4 * Copyright 2003-2004 Red Hat, Inc.
5 * 5 *
6 * The contents of this file are subject to the Open
7 * Software License version 1.1 that can be found at
8 * http://www.opensource.org/licenses/osl-1.1.txt and is included herein
9 * by reference.
10 * 6 *
11 * Alternatively, the contents of this file may be used under the terms 7 * This program is free software; you can redistribute it and/or modify
12 * of the GNU General Public License version 2 (the "GPL") as distributed 8 * it under the terms of the GNU General Public License as published by
13 * in the kernel source COPYING file, in which case the provisions of 9 * the Free Software Foundation; either version 2, or (at your option)
14 * the GPL are applicable instead of the above. If you wish to allow 10 * any later version.
15 * the use of your version of this file only under the terms of the 11 *
16 * GPL and not to allow others to use your version of this file under 12 * This program is distributed in the hope that it will be useful,
17 * the OSL, indicate your decision by deleting the provisions above and 13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
18 * replace them with the notice and other provisions required by the GPL. 14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 * If you do not delete the provisions above, a recipient may use your 15 * GNU General Public License for more details.
20 * version of this file under either the OSL or the GPL. 16 *
17 * You should have received a copy of the GNU General Public License
18 * along with this program; see the file COPYING. If not, write to
19 * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
20 *
21 *
22 * libata documentation is available via 'make {ps|pdf}docs',
23 * as Documentation/DocBook/libata.*
21 * 24 *
22 */ 25 */
23 26
diff --git a/drivers/scsi/sata_qstor.c b/drivers/scsi/sata_qstor.c
index 93fd06fb4f15..9c99ab433bd3 100644
--- a/drivers/scsi/sata_qstor.c
+++ b/drivers/scsi/sata_qstor.c
@@ -6,21 +6,24 @@
6 * Copyright 2005 Pacific Digital Corporation. 6 * Copyright 2005 Pacific Digital Corporation.
7 * (OSL/GPL code release authorized by Jalil Fadavi). 7 * (OSL/GPL code release authorized by Jalil Fadavi).
8 * 8 *
9 * The contents of this file are subject to the Open
10 * Software License version 1.1 that can be found at
11 * http://www.opensource.org/licenses/osl-1.1.txt and is included herein
12 * by reference.
13 * 9 *
14 * Alternatively, the contents of this file may be used under the terms 10 * This program is free software; you can redistribute it and/or modify
15 * of the GNU General Public License version 2 (the "GPL") as distributed 11 * it under the terms of the GNU General Public License as published by
16 * in the kernel source COPYING file, in which case the provisions of 12 * the Free Software Foundation; either version 2, or (at your option)
17 * the GPL are applicable instead of the above. If you wish to allow 13 * any later version.
18 * the use of your version of this file only under the terms of the 14 *
19 * GPL and not to allow others to use your version of this file under 15 * This program is distributed in the hope that it will be useful,
20 * the OSL, indicate your decision by deleting the provisions above and 16 * but WITHOUT ANY WARRANTY; without even the implied warranty of
21 * replace them with the notice and other provisions required by the GPL. 17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
22 * If you do not delete the provisions above, a recipient may use your 18 * GNU General Public License for more details.
23 * version of this file under either the OSL or the GPL. 19 *
20 * You should have received a copy of the GNU General Public License
21 * along with this program; see the file COPYING. If not, write to
22 * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
23 *
24 *
25 * libata documentation is available via 'make {ps|pdf}docs',
26 * as Documentation/DocBook/libata.*
24 * 27 *
25 */ 28 */
26 29
diff --git a/drivers/scsi/sata_sil.c b/drivers/scsi/sata_sil.c
index 9d24d6c328b4..71d49548f0a3 100644
--- a/drivers/scsi/sata_sil.c
+++ b/drivers/scsi/sata_sil.c
@@ -5,24 +5,27 @@
5 * Please ALWAYS copy linux-ide@vger.kernel.org 5 * Please ALWAYS copy linux-ide@vger.kernel.org
6 * on emails. 6 * on emails.
7 * 7 *
8 * Copyright 2003 Red Hat, Inc. 8 * Copyright 2003-2005 Red Hat, Inc.
9 * Copyright 2003 Benjamin Herrenschmidt 9 * Copyright 2003 Benjamin Herrenschmidt
10 * 10 *
11 * The contents of this file are subject to the Open
12 * Software License version 1.1 that can be found at
13 * http://www.opensource.org/licenses/osl-1.1.txt and is included herein
14 * by reference.
15 * 11 *
16 * Alternatively, the contents of this file may be used under the terms 12 * This program is free software; you can redistribute it and/or modify
17 * of the GNU General Public License version 2 (the "GPL") as distributed 13 * it under the terms of the GNU General Public License as published by
18 * in the kernel source COPYING file, in which case the provisions of 14 * the Free Software Foundation; either version 2, or (at your option)
19 * the GPL are applicable instead of the above. If you wish to allow 15 * any later version.
20 * the use of your version of this file only under the terms of the 16 *
21 * GPL and not to allow others to use your version of this file under 17 * This program is distributed in the hope that it will be useful,
22 * the OSL, indicate your decision by deleting the provisions above and 18 * but WITHOUT ANY WARRANTY; without even the implied warranty of
23 * replace them with the notice and other provisions required by the GPL. 19 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
24 * If you do not delete the provisions above, a recipient may use your 20 * GNU General Public License for more details.
25 * version of this file under either the OSL or the GPL. 21 *
22 * You should have received a copy of the GNU General Public License
23 * along with this program; see the file COPYING. If not, write to
24 * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
25 *
26 *
27 * libata documentation is available via 'make {ps|pdf}docs',
28 * as Documentation/DocBook/libata.*
26 * 29 *
27 * Documentation for SiI 3112: 30 * Documentation for SiI 3112:
28 * http://gkernel.sourceforge.net/specs/sii/3112A_SiI-DS-0095-B2.pdf.bz2 31 * http://gkernel.sourceforge.net/specs/sii/3112A_SiI-DS-0095-B2.pdf.bz2
diff --git a/drivers/scsi/sata_sis.c b/drivers/scsi/sata_sis.c
index b250ae0c7773..43af445b3ad2 100644
--- a/drivers/scsi/sata_sis.c
+++ b/drivers/scsi/sata_sis.c
@@ -7,21 +7,26 @@
7 * 7 *
8 * Copyright 2004 Uwe Koziolek 8 * Copyright 2004 Uwe Koziolek
9 * 9 *
10 * The contents of this file are subject to the Open
11 * Software License version 1.1 that can be found at
12 * http://www.opensource.org/licenses/osl-1.1.txt and is included herein
13 * by reference.
14 * 10 *
15 * Alternatively, the contents of this file may be used under the terms 11 * This program is free software; you can redistribute it and/or modify
16 * of the GNU General Public License version 2 (the "GPL") as distributed 12 * it under the terms of the GNU General Public License as published by
17 * in the kernel source COPYING file, in which case the provisions of 13 * the Free Software Foundation; either version 2, or (at your option)
18 * the GPL are applicable instead of the above. If you wish to allow 14 * any later version.
19 * the use of your version of this file only under the terms of the 15 *
20 * GPL and not to allow others to use your version of this file under 16 * This program is distributed in the hope that it will be useful,
21 * the OSL, indicate your decision by deleting the provisions above and 17 * but WITHOUT ANY WARRANTY; without even the implied warranty of
22 * replace them with the notice and other provisions required by the GPL. 18 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
23 * If you do not delete the provisions above, a recipient may use your 19 * GNU General Public License for more details.
24 * version of this file under either the OSL or the GPL. 20 *
21 * You should have received a copy of the GNU General Public License
22 * along with this program; see the file COPYING. If not, write to
23 * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
24 *
25 *
26 * libata documentation is available via 'make {ps|pdf}docs',
27 * as Documentation/DocBook/libata.*
28 *
29 * Hardware documentation available under NDA.
25 * 30 *
26 */ 31 */
27 32
diff --git a/drivers/scsi/sata_svw.c b/drivers/scsi/sata_svw.c
index 6fd2ce1ffcd8..19d3bb3b0fb6 100644
--- a/drivers/scsi/sata_svw.c
+++ b/drivers/scsi/sata_svw.c
@@ -13,21 +13,26 @@
13 * This driver probably works with non-Apple versions of the 13 * This driver probably works with non-Apple versions of the
14 * Broadcom chipset... 14 * Broadcom chipset...
15 * 15 *
16 * The contents of this file are subject to the Open
17 * Software License version 1.1 that can be found at
18 * http://www.opensource.org/licenses/osl-1.1.txt and is included herein
19 * by reference.
20 * 16 *
21 * Alternatively, the contents of this file may be used under the terms 17 * This program is free software; you can redistribute it and/or modify
22 * of the GNU General Public License version 2 (the "GPL") as distributed 18 * it under the terms of the GNU General Public License as published by
23 * in the kernel source COPYING file, in which case the provisions of 19 * the Free Software Foundation; either version 2, or (at your option)
24 * the GPL are applicable instead of the above. If you wish to allow 20 * any later version.
25 * the use of your version of this file only under the terms of the 21 *
26 * GPL and not to allow others to use your version of this file under 22 * This program is distributed in the hope that it will be useful,
27 * the OSL, indicate your decision by deleting the provisions above and 23 * but WITHOUT ANY WARRANTY; without even the implied warranty of
28 * replace them with the notice and other provisions required by the GPL. 24 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
29 * If you do not delete the provisions above, a recipient may use your 25 * GNU General Public License for more details.
30 * version of this file under either the OSL or the GPL. 26 *
27 * You should have received a copy of the GNU General Public License
28 * along with this program; see the file COPYING. If not, write to
29 * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
30 *
31 *
32 * libata documentation is available via 'make {ps|pdf}docs',
33 * as Documentation/DocBook/libata.*
34 *
35 * Hardware documentation available under NDA.
31 * 36 *
32 */ 37 */
33 38
diff --git a/drivers/scsi/sata_sx4.c b/drivers/scsi/sata_sx4.c
index a20d4285090a..c72fcc46f0fa 100644
--- a/drivers/scsi/sata_sx4.c
+++ b/drivers/scsi/sata_sx4.c
@@ -7,21 +7,26 @@
7 * 7 *
8 * Copyright 2003-2004 Red Hat, Inc. 8 * Copyright 2003-2004 Red Hat, Inc.
9 * 9 *
10 * The contents of this file are subject to the Open
11 * Software License version 1.1 that can be found at
12 * http://www.opensource.org/licenses/osl-1.1.txt and is included herein
13 * by reference.
14 * 10 *
15 * Alternatively, the contents of this file may be used under the terms 11 * This program is free software; you can redistribute it and/or modify
16 * of the GNU General Public License version 2 (the "GPL") as distributed 12 * it under the terms of the GNU General Public License as published by
17 * in the kernel source COPYING file, in which case the provisions of 13 * the Free Software Foundation; either version 2, or (at your option)
18 * the GPL are applicable instead of the above. If you wish to allow 14 * any later version.
19 * the use of your version of this file only under the terms of the 15 *
20 * GPL and not to allow others to use your version of this file under 16 * This program is distributed in the hope that it will be useful,
21 * the OSL, indicate your decision by deleting the provisions above and 17 * but WITHOUT ANY WARRANTY; without even the implied warranty of
22 * replace them with the notice and other provisions required by the GPL. 18 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
23 * If you do not delete the provisions above, a recipient may use your 19 * GNU General Public License for more details.
24 * version of this file under either the OSL or the GPL. 20 *
21 * You should have received a copy of the GNU General Public License
22 * along with this program; see the file COPYING. If not, write to
23 * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
24 *
25 *
26 * libata documentation is available via 'make {ps|pdf}docs',
27 * as Documentation/DocBook/libata.*
28 *
29 * Hardware documentation available under NDA.
25 * 30 *
26 */ 31 */
27 32
diff --git a/drivers/scsi/sata_uli.c b/drivers/scsi/sata_uli.c
index eb202a73bc0e..1566886815fb 100644
--- a/drivers/scsi/sata_uli.c
+++ b/drivers/scsi/sata_uli.c
@@ -1,21 +1,26 @@
1/* 1/*
2 * sata_uli.c - ULi Electronics SATA 2 * sata_uli.c - ULi Electronics SATA
3 * 3 *
4 * The contents of this file are subject to the Open
5 * Software License version 1.1 that can be found at
6 * http://www.opensource.org/licenses/osl-1.1.txt and is included herein
7 * by reference.
8 * 4 *
9 * Alternatively, the contents of this file may be used under the terms 5 * This program is free software; you can redistribute it and/or modify
10 * of the GNU General Public License version 2 (the "GPL") as distributed 6 * it under the terms of the GNU General Public License as published by
11 * in the kernel source COPYING file, in which case the provisions of 7 * the Free Software Foundation; either version 2, or (at your option)
12 * the GPL are applicable instead of the above. If you wish to allow 8 * any later version.
13 * the use of your version of this file only under the terms of the 9 *
14 * GPL and not to allow others to use your version of this file under 10 * This program is distributed in the hope that it will be useful,
15 * the OSL, indicate your decision by deleting the provisions above and 11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 * replace them with the notice and other provisions required by the GPL. 12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 * If you do not delete the provisions above, a recipient may use your 13 * GNU General Public License for more details.
18 * version of this file under either the OSL or the GPL. 14 *
15 * You should have received a copy of the GNU General Public License
16 * along with this program; see the file COPYING. If not, write to
17 * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
18 *
19 *
20 * libata documentation is available via 'make {ps|pdf}docs',
21 * as Documentation/DocBook/libata.*
22 *
23 * Hardware documentation available under NDA.
19 * 24 *
20 */ 25 */
21 26
diff --git a/drivers/scsi/sata_via.c b/drivers/scsi/sata_via.c
index feff10980487..128b996b07b7 100644
--- a/drivers/scsi/sata_via.c
+++ b/drivers/scsi/sata_via.c
@@ -1,34 +1,38 @@
1/* 1/*
2 sata_via.c - VIA Serial ATA controllers 2 * sata_via.c - VIA Serial ATA controllers
3 3 *
4 Maintained by: Jeff Garzik <jgarzik@pobox.com> 4 * Maintained by: Jeff Garzik <jgarzik@pobox.com>
5 Please ALWAYS copy linux-ide@vger.kernel.org 5 * Please ALWAYS copy linux-ide@vger.kernel.org
6 on emails. 6 on emails.
7 7 *
8 Copyright 2003-2004 Red Hat, Inc. All rights reserved. 8 * Copyright 2003-2004 Red Hat, Inc. All rights reserved.
9 Copyright 2003-2004 Jeff Garzik 9 * Copyright 2003-2004 Jeff Garzik
10 10 *
11 The contents of this file are subject to the Open 11 *
12 Software License version 1.1 that can be found at 12 * This program is free software; you can redistribute it and/or modify
13 http://www.opensource.org/licenses/osl-1.1.txt and is included herein 13 * it under the terms of the GNU General Public License as published by
14 by reference. 14 * the Free Software Foundation; either version 2, or (at your option)
15 15 * any later version.
16 Alternatively, the contents of this file may be used under the terms 16 *
17 of the GNU General Public License version 2 (the "GPL") as distributed 17 * This program is distributed in the hope that it will be useful,
18 in the kernel source COPYING file, in which case the provisions of 18 * but WITHOUT ANY WARRANTY; without even the implied warranty of
19 the GPL are applicable instead of the above. If you wish to allow 19 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
20 the use of your version of this file only under the terms of the 20 * GNU General Public License for more details.
21 GPL and not to allow others to use your version of this file under 21 *
22 the OSL, indicate your decision by deleting the provisions above and 22 * You should have received a copy of the GNU General Public License
23 replace them with the notice and other provisions required by the GPL. 23 * along with this program; see the file COPYING. If not, write to
24 If you do not delete the provisions above, a recipient may use your 24 * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
25 version of this file under either the OSL or the GPL. 25 *
26 26 *
27 ---------------------------------------------------------------------- 27 * libata documentation is available via 'make {ps|pdf}docs',
28 28 * as Documentation/DocBook/libata.*
29 To-do list: 29 *
30 * VT6421 PATA support 30 * Hardware documentation available under NDA.
31 31 *
32 *
33 * To-do list:
34 * - VT6421 PATA support
35 *
32 */ 36 */
33 37
34#include <linux/kernel.h> 38#include <linux/kernel.h>
diff --git a/drivers/scsi/sata_vsc.c b/drivers/scsi/sata_vsc.c
index 6f2562171be0..3985f344da4d 100644
--- a/drivers/scsi/sata_vsc.c
+++ b/drivers/scsi/sata_vsc.c
@@ -9,9 +9,29 @@
9 * 9 *
10 * Bits from Jeff Garzik, Copyright RedHat, Inc. 10 * Bits from Jeff Garzik, Copyright RedHat, Inc.
11 * 11 *
12 * This file is subject to the terms and conditions of the GNU General Public 12 *
13 * License. See the file "COPYING" in the main directory of this archive 13 * This program is free software; you can redistribute it and/or modify
14 * for more details. 14 * it under the terms of the GNU General Public License as published by
15 * the Free Software Foundation; either version 2, or (at your option)
16 * any later version.
17 *
18 * This program is distributed in the hope that it will be useful,
19 * but WITHOUT ANY WARRANTY; without even the implied warranty of
20 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21 * GNU General Public License for more details.
22 *
23 * You should have received a copy of the GNU General Public License
24 * along with this program; see the file COPYING. If not, write to
25 * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
26 *
27 *
28 * libata documentation is available via 'make {ps|pdf}docs',
29 * as Documentation/DocBook/libata.*
30 *
31 * Vitesse hardware documentation presumably available under NDA.
32 * Intel 31244 (same hardware interface) documentation presumably
33 * available from http://developer.intel.com/
34 *
15 */ 35 */
16 36
17#include <linux/kernel.h> 37#include <linux/kernel.h>
diff --git a/drivers/serial/21285.c b/drivers/serial/21285.c
index 0b10169961eb..aec39fb261ca 100644
--- a/drivers/serial/21285.c
+++ b/drivers/serial/21285.c
@@ -58,8 +58,7 @@ static const char serial21285_name[] = "Footbridge UART";
58 * int((BAUD_BASE - (baud >> 1)) / baud) 58 * int((BAUD_BASE - (baud >> 1)) / baud)
59 */ 59 */
60 60
61static void 61static void serial21285_stop_tx(struct uart_port *port)
62serial21285_stop_tx(struct uart_port *port, unsigned int tty_stop)
63{ 62{
64 if (tx_enabled(port)) { 63 if (tx_enabled(port)) {
65 disable_irq(IRQ_CONTX); 64 disable_irq(IRQ_CONTX);
@@ -67,8 +66,7 @@ serial21285_stop_tx(struct uart_port *port, unsigned int tty_stop)
67 } 66 }
68} 67}
69 68
70static void 69static void serial21285_start_tx(struct uart_port *port)
71serial21285_start_tx(struct uart_port *port, unsigned int tty_start)
72{ 70{
73 if (!tx_enabled(port)) { 71 if (!tx_enabled(port)) {
74 enable_irq(IRQ_CONTX); 72 enable_irq(IRQ_CONTX);
@@ -148,7 +146,7 @@ static irqreturn_t serial21285_tx_chars(int irq, void *dev_id, struct pt_regs *r
148 goto out; 146 goto out;
149 } 147 }
150 if (uart_circ_empty(xmit) || uart_tx_stopped(port)) { 148 if (uart_circ_empty(xmit) || uart_tx_stopped(port)) {
151 serial21285_stop_tx(port, 0); 149 serial21285_stop_tx(port);
152 goto out; 150 goto out;
153 } 151 }
154 152
@@ -164,7 +162,7 @@ static irqreturn_t serial21285_tx_chars(int irq, void *dev_id, struct pt_regs *r
164 uart_write_wakeup(port); 162 uart_write_wakeup(port);
165 163
166 if (uart_circ_empty(xmit)) 164 if (uart_circ_empty(xmit))
167 serial21285_stop_tx(port, 0); 165 serial21285_stop_tx(port);
168 166
169 out: 167 out:
170 return IRQ_HANDLED; 168 return IRQ_HANDLED;
diff --git a/drivers/serial/8250.c b/drivers/serial/8250.c
index 7e8fc7c1d4cc..30a0a3d10145 100644
--- a/drivers/serial/8250.c
+++ b/drivers/serial/8250.c
@@ -1001,7 +1001,7 @@ static inline void __stop_tx(struct uart_8250_port *p)
1001 } 1001 }
1002} 1002}
1003 1003
1004static void serial8250_stop_tx(struct uart_port *port, unsigned int tty_stop) 1004static void serial8250_stop_tx(struct uart_port *port)
1005{ 1005{
1006 struct uart_8250_port *up = (struct uart_8250_port *)port; 1006 struct uart_8250_port *up = (struct uart_8250_port *)port;
1007 1007
@@ -1018,7 +1018,7 @@ static void serial8250_stop_tx(struct uart_port *port, unsigned int tty_stop)
1018 1018
1019static void transmit_chars(struct uart_8250_port *up); 1019static void transmit_chars(struct uart_8250_port *up);
1020 1020
1021static void serial8250_start_tx(struct uart_port *port, unsigned int tty_start) 1021static void serial8250_start_tx(struct uart_port *port)
1022{ 1022{
1023 struct uart_8250_port *up = (struct uart_8250_port *)port; 1023 struct uart_8250_port *up = (struct uart_8250_port *)port;
1024 1024
@@ -1158,7 +1158,11 @@ static _INLINE_ void transmit_chars(struct uart_8250_port *up)
1158 up->port.x_char = 0; 1158 up->port.x_char = 0;
1159 return; 1159 return;
1160 } 1160 }
1161 if (uart_circ_empty(xmit) || uart_tx_stopped(&up->port)) { 1161 if (uart_tx_stopped(&up->port)) {
1162 serial8250_stop_tx(&up->port);
1163 return;
1164 }
1165 if (uart_circ_empty(xmit)) {
1162 __stop_tx(up); 1166 __stop_tx(up);
1163 return; 1167 return;
1164 } 1168 }
@@ -2586,82 +2590,3 @@ module_param_array(probe_rsa, ulong, &probe_rsa_count, 0444);
2586MODULE_PARM_DESC(probe_rsa, "Probe I/O ports for RSA"); 2590MODULE_PARM_DESC(probe_rsa, "Probe I/O ports for RSA");
2587#endif 2591#endif
2588MODULE_ALIAS_CHARDEV_MAJOR(TTY_MAJOR); 2592MODULE_ALIAS_CHARDEV_MAJOR(TTY_MAJOR);
2589
2590/**
2591 * register_serial - configure a 16x50 serial port at runtime
2592 * @req: request structure
2593 *
2594 * Configure the serial port specified by the request. If the
2595 * port exists and is in use an error is returned. If the port
2596 * is not currently in the table it is added.
2597 *
2598 * The port is then probed and if necessary the IRQ is autodetected
2599 * If this fails an error is returned.
2600 *
2601 * On success the port is ready to use and the line number is returned.
2602 *
2603 * Note: this function is deprecated - use serial8250_register_port
2604 * instead.
2605 */
2606int register_serial(struct serial_struct *req)
2607{
2608 struct uart_port port;
2609
2610 port.iobase = req->port;
2611 port.membase = req->iomem_base;
2612 port.irq = req->irq;
2613 port.uartclk = req->baud_base * 16;
2614 port.fifosize = req->xmit_fifo_size;
2615 port.regshift = req->iomem_reg_shift;
2616 port.iotype = req->io_type;
2617 port.flags = req->flags | UPF_BOOT_AUTOCONF;
2618 port.mapbase = req->iomap_base;
2619 port.dev = NULL;
2620
2621 if (share_irqs)
2622 port.flags |= UPF_SHARE_IRQ;
2623
2624 if (HIGH_BITS_OFFSET)
2625 port.iobase |= (long) req->port_high << HIGH_BITS_OFFSET;
2626
2627 /*
2628 * If a clock rate wasn't specified by the low level driver, then
2629 * default to the standard clock rate. This should be 115200 (*16)
2630 * and should not depend on the architecture's BASE_BAUD definition.
2631 * However, since this API will be deprecated, it's probably a
2632 * better idea to convert the drivers to use the new API
2633 * (serial8250_register_port and serial8250_unregister_port).
2634 */
2635 if (port.uartclk == 0) {
2636 printk(KERN_WARNING
2637 "Serial: registering port at [%08x,%08lx,%p] irq %d with zero baud_base\n",
2638 port.iobase, port.mapbase, port.membase, port.irq);
2639 printk(KERN_WARNING "Serial: see %s:%d for more information\n",
2640 __FILE__, __LINE__);
2641 dump_stack();
2642
2643 /*
2644 * Fix it up for now, but this is only a temporary measure.
2645 */
2646 port.uartclk = BASE_BAUD * 16;
2647 }
2648
2649 return serial8250_register_port(&port);
2650}
2651EXPORT_SYMBOL(register_serial);
2652
2653/**
2654 * unregister_serial - remove a 16x50 serial port at runtime
2655 * @line: serial line number
2656 *
2657 * Remove one serial port. This may not be called from interrupt
2658 * context. We hand the port back to our local PM control.
2659 *
2660 * Note: this function is deprecated - use serial8250_unregister_port
2661 * instead.
2662 */
2663void unregister_serial(int line)
2664{
2665 serial8250_unregister_port(line);
2666}
2667EXPORT_SYMBOL(unregister_serial);
diff --git a/drivers/serial/8250.h b/drivers/serial/8250.h
index 9225c82faeb8..b1b459efda52 100644
--- a/drivers/serial/8250.h
+++ b/drivers/serial/8250.h
@@ -16,11 +16,7 @@
16 */ 16 */
17 17
18#include <linux/config.h> 18#include <linux/config.h>
19 19#include <linux/serial_8250.h>
20int serial8250_register_port(struct uart_port *);
21void serial8250_unregister_port(int line);
22void serial8250_suspend_port(int line);
23void serial8250_resume_port(int line);
24 20
25struct old_serial_port { 21struct old_serial_port {
26 unsigned int uart; 22 unsigned int uart;
diff --git a/drivers/serial/Kconfig b/drivers/serial/Kconfig
index b87122a08488..db8f39c30096 100644
--- a/drivers/serial/Kconfig
+++ b/drivers/serial/Kconfig
@@ -830,7 +830,7 @@ config SERIAL_M32R_PLDSIO
830 830
831config SERIAL_TXX9 831config SERIAL_TXX9
832 bool "TMPTX39XX/49XX SIO support" 832 bool "TMPTX39XX/49XX SIO support"
833 depends HAS_TXX9_SERIAL 833 depends HAS_TXX9_SERIAL && BROKEN
834 select SERIAL_CORE 834 select SERIAL_CORE
835 default y 835 default y
836 836
diff --git a/drivers/serial/amba-pl010.c b/drivers/serial/amba-pl010.c
index 2884b310e54d..978e12437e61 100644
--- a/drivers/serial/amba-pl010.c
+++ b/drivers/serial/amba-pl010.c
@@ -105,7 +105,7 @@ struct uart_amba_port {
105 unsigned int old_status; 105 unsigned int old_status;
106}; 106};
107 107
108static void pl010_stop_tx(struct uart_port *port, unsigned int tty_stop) 108static void pl010_stop_tx(struct uart_port *port)
109{ 109{
110 unsigned int cr; 110 unsigned int cr;
111 111
@@ -114,7 +114,7 @@ static void pl010_stop_tx(struct uart_port *port, unsigned int tty_stop)
114 UART_PUT_CR(port, cr); 114 UART_PUT_CR(port, cr);
115} 115}
116 116
117static void pl010_start_tx(struct uart_port *port, unsigned int tty_start) 117static void pl010_start_tx(struct uart_port *port)
118{ 118{
119 unsigned int cr; 119 unsigned int cr;
120 120
@@ -219,7 +219,7 @@ static void pl010_tx_chars(struct uart_port *port)
219 return; 219 return;
220 } 220 }
221 if (uart_circ_empty(xmit) || uart_tx_stopped(port)) { 221 if (uart_circ_empty(xmit) || uart_tx_stopped(port)) {
222 pl010_stop_tx(port, 0); 222 pl010_stop_tx(port);
223 return; 223 return;
224 } 224 }
225 225
@@ -236,7 +236,7 @@ static void pl010_tx_chars(struct uart_port *port)
236 uart_write_wakeup(port); 236 uart_write_wakeup(port);
237 237
238 if (uart_circ_empty(xmit)) 238 if (uart_circ_empty(xmit))
239 pl010_stop_tx(port, 0); 239 pl010_stop_tx(port);
240} 240}
241 241
242static void pl010_modem_status(struct uart_port *port) 242static void pl010_modem_status(struct uart_port *port)
diff --git a/drivers/serial/amba-pl011.c b/drivers/serial/amba-pl011.c
index 7db88ee18f75..56071309744c 100644
--- a/drivers/serial/amba-pl011.c
+++ b/drivers/serial/amba-pl011.c
@@ -74,7 +74,7 @@ struct uart_amba_port {
74 unsigned int old_status; 74 unsigned int old_status;
75}; 75};
76 76
77static void pl011_stop_tx(struct uart_port *port, unsigned int tty_stop) 77static void pl011_stop_tx(struct uart_port *port)
78{ 78{
79 struct uart_amba_port *uap = (struct uart_amba_port *)port; 79 struct uart_amba_port *uap = (struct uart_amba_port *)port;
80 80
@@ -82,7 +82,7 @@ static void pl011_stop_tx(struct uart_port *port, unsigned int tty_stop)
82 writew(uap->im, uap->port.membase + UART011_IMSC); 82 writew(uap->im, uap->port.membase + UART011_IMSC);
83} 83}
84 84
85static void pl011_start_tx(struct uart_port *port, unsigned int tty_start) 85static void pl011_start_tx(struct uart_port *port)
86{ 86{
87 struct uart_amba_port *uap = (struct uart_amba_port *)port; 87 struct uart_amba_port *uap = (struct uart_amba_port *)port;
88 88
@@ -184,7 +184,7 @@ static void pl011_tx_chars(struct uart_amba_port *uap)
184 return; 184 return;
185 } 185 }
186 if (uart_circ_empty(xmit) || uart_tx_stopped(&uap->port)) { 186 if (uart_circ_empty(xmit) || uart_tx_stopped(&uap->port)) {
187 pl011_stop_tx(&uap->port, 0); 187 pl011_stop_tx(&uap->port);
188 return; 188 return;
189 } 189 }
190 190
@@ -201,7 +201,7 @@ static void pl011_tx_chars(struct uart_amba_port *uap)
201 uart_write_wakeup(&uap->port); 201 uart_write_wakeup(&uap->port);
202 202
203 if (uart_circ_empty(xmit)) 203 if (uart_circ_empty(xmit))
204 pl011_stop_tx(&uap->port, 0); 204 pl011_stop_tx(&uap->port);
205} 205}
206 206
207static void pl011_modem_status(struct uart_amba_port *uap) 207static void pl011_modem_status(struct uart_amba_port *uap)
diff --git a/drivers/serial/au1x00_uart.c b/drivers/serial/au1x00_uart.c
index 6104aeef1243..a274ebf256a1 100644
--- a/drivers/serial/au1x00_uart.c
+++ b/drivers/serial/au1x00_uart.c
@@ -200,7 +200,7 @@ static void autoconfig(struct uart_8250_port *up, unsigned int probeflags)
200 DEBUG_AUTOCONF("type=%s\n", uart_config[up->port.type].name); 200 DEBUG_AUTOCONF("type=%s\n", uart_config[up->port.type].name);
201} 201}
202 202
203static void serial8250_stop_tx(struct uart_port *port, unsigned int tty_stop) 203static void serial8250_stop_tx(struct uart_port *port)
204{ 204{
205 struct uart_8250_port *up = (struct uart_8250_port *)port; 205 struct uart_8250_port *up = (struct uart_8250_port *)port;
206 206
@@ -210,7 +210,7 @@ static void serial8250_stop_tx(struct uart_port *port, unsigned int tty_stop)
210 } 210 }
211} 211}
212 212
213static void serial8250_start_tx(struct uart_port *port, unsigned int tty_start) 213static void serial8250_start_tx(struct uart_port *port)
214{ 214{
215 struct uart_8250_port *up = (struct uart_8250_port *)port; 215 struct uart_8250_port *up = (struct uart_8250_port *)port;
216 216
@@ -337,7 +337,7 @@ static _INLINE_ void transmit_chars(struct uart_8250_port *up)
337 return; 337 return;
338 } 338 }
339 if (uart_circ_empty(xmit) || uart_tx_stopped(&up->port)) { 339 if (uart_circ_empty(xmit) || uart_tx_stopped(&up->port)) {
340 serial8250_stop_tx(&up->port, 0); 340 serial8250_stop_tx(&up->port);
341 return; 341 return;
342 } 342 }
343 343
@@ -356,7 +356,7 @@ static _INLINE_ void transmit_chars(struct uart_8250_port *up)
356 DEBUG_INTR("THRE..."); 356 DEBUG_INTR("THRE...");
357 357
358 if (uart_circ_empty(xmit)) 358 if (uart_circ_empty(xmit))
359 serial8250_stop_tx(&up->port, 0); 359 serial8250_stop_tx(&up->port);
360} 360}
361 361
362static _INLINE_ void check_modem_status(struct uart_8250_port *up) 362static _INLINE_ void check_modem_status(struct uart_8250_port *up)
diff --git a/drivers/serial/clps711x.c b/drivers/serial/clps711x.c
index e92522b33c48..d822896b488c 100644
--- a/drivers/serial/clps711x.c
+++ b/drivers/serial/clps711x.c
@@ -69,8 +69,7 @@
69 69
70#define tx_enabled(port) ((port)->unused[0]) 70#define tx_enabled(port) ((port)->unused[0])
71 71
72static void 72static void clps711xuart_stop_tx(struct uart_port *port)
73clps711xuart_stop_tx(struct uart_port *port, unsigned int tty_stop)
74{ 73{
75 if (tx_enabled(port)) { 74 if (tx_enabled(port)) {
76 disable_irq(TX_IRQ(port)); 75 disable_irq(TX_IRQ(port));
@@ -78,8 +77,7 @@ clps711xuart_stop_tx(struct uart_port *port, unsigned int tty_stop)
78 } 77 }
79} 78}
80 79
81static void 80static void clps711xuart_start_tx(struct uart_port *port)
82clps711xuart_start_tx(struct uart_port *port, unsigned int tty_start)
83{ 81{
84 if (!tx_enabled(port)) { 82 if (!tx_enabled(port)) {
85 enable_irq(TX_IRQ(port)); 83 enable_irq(TX_IRQ(port));
@@ -165,7 +163,7 @@ static irqreturn_t clps711xuart_int_tx(int irq, void *dev_id, struct pt_regs *re
165 return IRQ_HANDLED; 163 return IRQ_HANDLED;
166 } 164 }
167 if (uart_circ_empty(xmit) || uart_tx_stopped(port)) { 165 if (uart_circ_empty(xmit) || uart_tx_stopped(port)) {
168 clps711xuart_stop_tx(port, 0); 166 clps711xuart_stop_tx(port);
169 return IRQ_HANDLED; 167 return IRQ_HANDLED;
170 } 168 }
171 169
@@ -182,7 +180,7 @@ static irqreturn_t clps711xuart_int_tx(int irq, void *dev_id, struct pt_regs *re
182 uart_write_wakeup(port); 180 uart_write_wakeup(port);
183 181
184 if (uart_circ_empty(xmit)) 182 if (uart_circ_empty(xmit))
185 clps711xuart_stop_tx(port, 0); 183 clps711xuart_stop_tx(port);
186 184
187 return IRQ_HANDLED; 185 return IRQ_HANDLED;
188} 186}
diff --git a/drivers/serial/cpm_uart/cpm_uart_core.c b/drivers/serial/cpm_uart/cpm_uart_core.c
index d639ac92a117..282b32351d8e 100644
--- a/drivers/serial/cpm_uart/cpm_uart_core.c
+++ b/drivers/serial/cpm_uart/cpm_uart_core.c
@@ -124,7 +124,7 @@ static unsigned int cpm_uart_get_mctrl(struct uart_port *port)
124/* 124/*
125 * Stop transmitter 125 * Stop transmitter
126 */ 126 */
127static void cpm_uart_stop_tx(struct uart_port *port, unsigned int tty_stop) 127static void cpm_uart_stop_tx(struct uart_port *port)
128{ 128{
129 struct uart_cpm_port *pinfo = (struct uart_cpm_port *)port; 129 struct uart_cpm_port *pinfo = (struct uart_cpm_port *)port;
130 volatile smc_t *smcp = pinfo->smcp; 130 volatile smc_t *smcp = pinfo->smcp;
@@ -141,7 +141,7 @@ static void cpm_uart_stop_tx(struct uart_port *port, unsigned int tty_stop)
141/* 141/*
142 * Start transmitter 142 * Start transmitter
143 */ 143 */
144static void cpm_uart_start_tx(struct uart_port *port, unsigned int tty_start) 144static void cpm_uart_start_tx(struct uart_port *port)
145{ 145{
146 struct uart_cpm_port *pinfo = (struct uart_cpm_port *)port; 146 struct uart_cpm_port *pinfo = (struct uart_cpm_port *)port;
147 volatile smc_t *smcp = pinfo->smcp; 147 volatile smc_t *smcp = pinfo->smcp;
@@ -623,7 +623,7 @@ static int cpm_uart_tx_pump(struct uart_port *port)
623 } 623 }
624 624
625 if (uart_circ_empty(xmit) || uart_tx_stopped(port)) { 625 if (uart_circ_empty(xmit) || uart_tx_stopped(port)) {
626 cpm_uart_stop_tx(port, 0); 626 cpm_uart_stop_tx(port);
627 return 0; 627 return 0;
628 } 628 }
629 629
@@ -656,7 +656,7 @@ static int cpm_uart_tx_pump(struct uart_port *port)
656 uart_write_wakeup(port); 656 uart_write_wakeup(port);
657 657
658 if (uart_circ_empty(xmit)) { 658 if (uart_circ_empty(xmit)) {
659 cpm_uart_stop_tx(port, 0); 659 cpm_uart_stop_tx(port);
660 return 0; 660 return 0;
661 } 661 }
662 662
diff --git a/drivers/serial/dz.c b/drivers/serial/dz.c
index 97824eeeafae..e63b9dffc8d7 100644
--- a/drivers/serial/dz.c
+++ b/drivers/serial/dz.c
@@ -112,7 +112,7 @@ static inline void dz_out(struct dz_port *dport, unsigned offset,
112 * ------------------------------------------------------------ 112 * ------------------------------------------------------------
113 */ 113 */
114 114
115static void dz_stop_tx(struct uart_port *uport, unsigned int tty_stop) 115static void dz_stop_tx(struct uart_port *uport)
116{ 116{
117 struct dz_port *dport = (struct dz_port *)uport; 117 struct dz_port *dport = (struct dz_port *)uport;
118 unsigned short tmp, mask = 1 << dport->port.line; 118 unsigned short tmp, mask = 1 << dport->port.line;
@@ -125,7 +125,7 @@ static void dz_stop_tx(struct uart_port *uport, unsigned int tty_stop)
125 spin_unlock_irqrestore(&dport->port.lock, flags); 125 spin_unlock_irqrestore(&dport->port.lock, flags);
126} 126}
127 127
128static void dz_start_tx(struct uart_port *uport, unsigned int tty_start) 128static void dz_start_tx(struct uart_port *uport)
129{ 129{
130 struct dz_port *dport = (struct dz_port *)uport; 130 struct dz_port *dport = (struct dz_port *)uport;
131 unsigned short tmp, mask = 1 << dport->port.line; 131 unsigned short tmp, mask = 1 << dport->port.line;
@@ -290,7 +290,7 @@ static inline void dz_transmit_chars(struct dz_port *dport)
290 } 290 }
291 /* if nothing to do or stopped or hardware stopped */ 291 /* if nothing to do or stopped or hardware stopped */
292 if (uart_circ_empty(xmit) || uart_tx_stopped(&dport->port)) { 292 if (uart_circ_empty(xmit) || uart_tx_stopped(&dport->port)) {
293 dz_stop_tx(&dport->port, 0); 293 dz_stop_tx(&dport->port);
294 return; 294 return;
295 } 295 }
296 296
@@ -308,7 +308,7 @@ static inline void dz_transmit_chars(struct dz_port *dport)
308 308
309 /* Are we done */ 309 /* Are we done */
310 if (uart_circ_empty(xmit)) 310 if (uart_circ_empty(xmit))
311 dz_stop_tx(&dport->port, 0); 311 dz_stop_tx(&dport->port);
312} 312}
313 313
314/* 314/*
@@ -440,7 +440,7 @@ static int dz_startup(struct uart_port *uport)
440 */ 440 */
441static void dz_shutdown(struct uart_port *uport) 441static void dz_shutdown(struct uart_port *uport)
442{ 442{
443 dz_stop_tx(uport, 0); 443 dz_stop_tx(uport);
444} 444}
445 445
446/* 446/*
diff --git a/drivers/serial/icom.c b/drivers/serial/icom.c
index c112b32764e8..79f8df4d66b7 100644
--- a/drivers/serial/icom.c
+++ b/drivers/serial/icom.c
@@ -989,18 +989,16 @@ static unsigned int icom_get_mctrl(struct uart_port *port)
989 return result; 989 return result;
990} 990}
991 991
992static void icom_stop_tx(struct uart_port *port, unsigned int tty_stop) 992static void icom_stop_tx(struct uart_port *port)
993{ 993{
994 unsigned char cmdReg; 994 unsigned char cmdReg;
995 995
996 if (tty_stop) { 996 trace(ICOM_PORT, "STOP", 0);
997 trace(ICOM_PORT, "STOP", 0); 997 cmdReg = readb(&ICOM_PORT->dram->CmdReg);
998 cmdReg = readb(&ICOM_PORT->dram->CmdReg); 998 writeb(cmdReg | CMD_HOLD_XMIT, &ICOM_PORT->dram->CmdReg);
999 writeb(cmdReg | CMD_HOLD_XMIT, &ICOM_PORT->dram->CmdReg);
1000 }
1001} 999}
1002 1000
1003static void icom_start_tx(struct uart_port *port, unsigned int tty_start) 1001static void icom_start_tx(struct uart_port *port)
1004{ 1002{
1005 unsigned char cmdReg; 1003 unsigned char cmdReg;
1006 1004
diff --git a/drivers/serial/imx.c b/drivers/serial/imx.c
index 01a8726a3f97..4c985e6b3784 100644
--- a/drivers/serial/imx.c
+++ b/drivers/serial/imx.c
@@ -124,7 +124,7 @@ static void imx_timeout(unsigned long data)
124/* 124/*
125 * interrupts disabled on entry 125 * interrupts disabled on entry
126 */ 126 */
127static void imx_stop_tx(struct uart_port *port, unsigned int tty_stop) 127static void imx_stop_tx(struct uart_port *port)
128{ 128{
129 struct imx_port *sport = (struct imx_port *)port; 129 struct imx_port *sport = (struct imx_port *)port;
130 UCR1((u32)sport->port.membase) &= ~UCR1_TXMPTYEN; 130 UCR1((u32)sport->port.membase) &= ~UCR1_TXMPTYEN;
@@ -165,13 +165,13 @@ static inline void imx_transmit_buffer(struct imx_port *sport)
165 } while (!(UTS((u32)sport->port.membase) & UTS_TXFULL)); 165 } while (!(UTS((u32)sport->port.membase) & UTS_TXFULL));
166 166
167 if (uart_circ_empty(xmit)) 167 if (uart_circ_empty(xmit))
168 imx_stop_tx(&sport->port, 0); 168 imx_stop_tx(&sport->port);
169} 169}
170 170
171/* 171/*
172 * interrupts disabled on entry 172 * interrupts disabled on entry
173 */ 173 */
174static void imx_start_tx(struct uart_port *port, unsigned int tty_start) 174static void imx_start_tx(struct uart_port *port)
175{ 175{
176 struct imx_port *sport = (struct imx_port *)port; 176 struct imx_port *sport = (struct imx_port *)port;
177 177
@@ -196,7 +196,7 @@ static irqreturn_t imx_txint(int irq, void *dev_id, struct pt_regs *regs)
196 } 196 }
197 197
198 if (uart_circ_empty(xmit) || uart_tx_stopped(&sport->port)) { 198 if (uart_circ_empty(xmit) || uart_tx_stopped(&sport->port)) {
199 imx_stop_tx(&sport->port, 0); 199 imx_stop_tx(&sport->port);
200 goto out; 200 goto out;
201 } 201 }
202 202
@@ -291,13 +291,31 @@ static unsigned int imx_tx_empty(struct uart_port *port)
291 return USR2((u32)sport->port.membase) & USR2_TXDC ? TIOCSER_TEMT : 0; 291 return USR2((u32)sport->port.membase) & USR2_TXDC ? TIOCSER_TEMT : 0;
292} 292}
293 293
294/*
295 * We have a modem side uart, so the meanings of RTS and CTS are inverted.
296 */
294static unsigned int imx_get_mctrl(struct uart_port *port) 297static unsigned int imx_get_mctrl(struct uart_port *port)
295{ 298{
296 return TIOCM_CTS | TIOCM_DSR | TIOCM_CAR; 299 struct imx_port *sport = (struct imx_port *)port;
300 unsigned int tmp = TIOCM_DSR | TIOCM_CAR;
301
302 if (USR1((u32)sport->port.membase) & USR1_RTSS)
303 tmp |= TIOCM_CTS;
304
305 if (UCR2((u32)sport->port.membase) & UCR2_CTS)
306 tmp |= TIOCM_RTS;
307
308 return tmp;
297} 309}
298 310
299static void imx_set_mctrl(struct uart_port *port, unsigned int mctrl) 311static void imx_set_mctrl(struct uart_port *port, unsigned int mctrl)
300{ 312{
313 struct imx_port *sport = (struct imx_port *)port;
314
315 if (mctrl & TIOCM_RTS)
316 UCR2((u32)sport->port.membase) |= UCR2_CTS;
317 else
318 UCR2((u32)sport->port.membase) &= ~UCR2_CTS;
301} 319}
302 320
303/* 321/*
diff --git a/drivers/serial/ioc4_serial.c b/drivers/serial/ioc4_serial.c
index 793c3a7cbe47..0c5c96a582b3 100644
--- a/drivers/serial/ioc4_serial.c
+++ b/drivers/serial/ioc4_serial.c
@@ -2373,10 +2373,9 @@ static unsigned int ic4_tx_empty(struct uart_port *the_port)
2373/** 2373/**
2374 * ic4_stop_tx - stop the transmitter 2374 * ic4_stop_tx - stop the transmitter
2375 * @port: Port to operate on 2375 * @port: Port to operate on
2376 * @tty_stop: Set to 1 if called via uart_stop
2377 * 2376 *
2378 */ 2377 */
2379static void ic4_stop_tx(struct uart_port *the_port, unsigned int tty_stop) 2378static void ic4_stop_tx(struct uart_port *the_port)
2380{ 2379{
2381} 2380}
2382 2381
@@ -2471,10 +2470,9 @@ static unsigned int ic4_get_mctrl(struct uart_port *the_port)
2471/** 2470/**
2472 * ic4_start_tx - Start transmitter, flush any output 2471 * ic4_start_tx - Start transmitter, flush any output
2473 * @port: Port to operate on 2472 * @port: Port to operate on
2474 * @tty_stop: Set to 1 if called via uart_start
2475 * 2473 *
2476 */ 2474 */
2477static void ic4_start_tx(struct uart_port *the_port, unsigned int tty_stop) 2475static void ic4_start_tx(struct uart_port *the_port)
2478{ 2476{
2479 struct ioc4_port *port = get_ioc4_port(the_port); 2477 struct ioc4_port *port = get_ioc4_port(the_port);
2480 unsigned long flags; 2478 unsigned long flags;
diff --git a/drivers/serial/ip22zilog.c b/drivers/serial/ip22zilog.c
index ea5bf4d4daa3..ef132349f310 100644
--- a/drivers/serial/ip22zilog.c
+++ b/drivers/serial/ip22zilog.c
@@ -592,7 +592,7 @@ static void ip22zilog_set_mctrl(struct uart_port *port, unsigned int mctrl)
592} 592}
593 593
594/* The port lock is held and interrupts are disabled. */ 594/* The port lock is held and interrupts are disabled. */
595static void ip22zilog_stop_tx(struct uart_port *port, unsigned int tty_stop) 595static void ip22zilog_stop_tx(struct uart_port *port)
596{ 596{
597 struct uart_ip22zilog_port *up = (struct uart_ip22zilog_port *) port; 597 struct uart_ip22zilog_port *up = (struct uart_ip22zilog_port *) port;
598 598
@@ -600,7 +600,7 @@ static void ip22zilog_stop_tx(struct uart_port *port, unsigned int tty_stop)
600} 600}
601 601
602/* The port lock is held and interrupts are disabled. */ 602/* The port lock is held and interrupts are disabled. */
603static void ip22zilog_start_tx(struct uart_port *port, unsigned int tty_start) 603static void ip22zilog_start_tx(struct uart_port *port)
604{ 604{
605 struct uart_ip22zilog_port *up = (struct uart_ip22zilog_port *) port; 605 struct uart_ip22zilog_port *up = (struct uart_ip22zilog_port *) port;
606 struct zilog_channel *channel = ZILOG_CHANNEL_FROM_PORT(port); 606 struct zilog_channel *channel = ZILOG_CHANNEL_FROM_PORT(port);
diff --git a/drivers/serial/jsm/jsm_tty.c b/drivers/serial/jsm/jsm_tty.c
index 98de2258fd06..6fa0d62d6f68 100644
--- a/drivers/serial/jsm/jsm_tty.c
+++ b/drivers/serial/jsm/jsm_tty.c
@@ -113,7 +113,7 @@ static void jsm_tty_set_mctrl(struct uart_port *port, unsigned int mctrl)
113 udelay(10); 113 udelay(10);
114} 114}
115 115
116static void jsm_tty_start_tx(struct uart_port *port, unsigned int tty_start) 116static void jsm_tty_start_tx(struct uart_port *port)
117{ 117{
118 struct jsm_channel *channel = (struct jsm_channel *)port; 118 struct jsm_channel *channel = (struct jsm_channel *)port;
119 119
@@ -125,7 +125,7 @@ static void jsm_tty_start_tx(struct uart_port *port, unsigned int tty_start)
125 jsm_printk(IOCTL, INFO, &channel->ch_bd->pci_dev, "finish\n"); 125 jsm_printk(IOCTL, INFO, &channel->ch_bd->pci_dev, "finish\n");
126} 126}
127 127
128static void jsm_tty_stop_tx(struct uart_port *port, unsigned int tty_stop) 128static void jsm_tty_stop_tx(struct uart_port *port)
129{ 129{
130 struct jsm_channel *channel = (struct jsm_channel *)port; 130 struct jsm_channel *channel = (struct jsm_channel *)port;
131 131
diff --git a/drivers/serial/m32r_sio.c b/drivers/serial/m32r_sio.c
index 9b50560b9d16..b0ecc7537ce5 100644
--- a/drivers/serial/m32r_sio.c
+++ b/drivers/serial/m32r_sio.c
@@ -275,7 +275,7 @@ serial_out(struct uart_sio_port *up, int offset, int value)
275 __sio_out(value, offset); 275 __sio_out(value, offset);
276} 276}
277 277
278static void m32r_sio_stop_tx(struct uart_port *port, unsigned int tty_stop) 278static void m32r_sio_stop_tx(struct uart_port *port)
279{ 279{
280 struct uart_sio_port *up = (struct uart_sio_port *)port; 280 struct uart_sio_port *up = (struct uart_sio_port *)port;
281 281
@@ -285,7 +285,7 @@ static void m32r_sio_stop_tx(struct uart_port *port, unsigned int tty_stop)
285 } 285 }
286} 286}
287 287
288static void m32r_sio_start_tx(struct uart_port *port, unsigned int tty_start) 288static void m32r_sio_start_tx(struct uart_port *port)
289{ 289{
290#ifdef CONFIG_SERIAL_M32R_PLDSIO 290#ifdef CONFIG_SERIAL_M32R_PLDSIO
291 struct uart_sio_port *up = (struct uart_sio_port *)port; 291 struct uart_sio_port *up = (struct uart_sio_port *)port;
@@ -425,7 +425,7 @@ static _INLINE_ void transmit_chars(struct uart_sio_port *up)
425 return; 425 return;
426 } 426 }
427 if (uart_circ_empty(xmit) || uart_tx_stopped(&up->port)) { 427 if (uart_circ_empty(xmit) || uart_tx_stopped(&up->port)) {
428 m32r_sio_stop_tx(&up->port, 0); 428 m32r_sio_stop_tx(&up->port);
429 return; 429 return;
430 } 430 }
431 431
@@ -446,7 +446,7 @@ static _INLINE_ void transmit_chars(struct uart_sio_port *up)
446 DEBUG_INTR("THRE..."); 446 DEBUG_INTR("THRE...");
447 447
448 if (uart_circ_empty(xmit)) 448 if (uart_circ_empty(xmit))
449 m32r_sio_stop_tx(&up->port, 0); 449 m32r_sio_stop_tx(&up->port);
450} 450}
451 451
452/* 452/*
diff --git a/drivers/serial/mpc52xx_uart.c b/drivers/serial/mpc52xx_uart.c
index 2a5cf174ca30..a3cd0ee8486d 100644
--- a/drivers/serial/mpc52xx_uart.c
+++ b/drivers/serial/mpc52xx_uart.c
@@ -119,7 +119,7 @@ mpc52xx_uart_get_mctrl(struct uart_port *port)
119} 119}
120 120
121static void 121static void
122mpc52xx_uart_stop_tx(struct uart_port *port, unsigned int tty_stop) 122mpc52xx_uart_stop_tx(struct uart_port *port)
123{ 123{
124 /* port->lock taken by caller */ 124 /* port->lock taken by caller */
125 port->read_status_mask &= ~MPC52xx_PSC_IMR_TXRDY; 125 port->read_status_mask &= ~MPC52xx_PSC_IMR_TXRDY;
@@ -127,7 +127,7 @@ mpc52xx_uart_stop_tx(struct uart_port *port, unsigned int tty_stop)
127} 127}
128 128
129static void 129static void
130mpc52xx_uart_start_tx(struct uart_port *port, unsigned int tty_start) 130mpc52xx_uart_start_tx(struct uart_port *port)
131{ 131{
132 /* port->lock taken by caller */ 132 /* port->lock taken by caller */
133 port->read_status_mask |= MPC52xx_PSC_IMR_TXRDY; 133 port->read_status_mask |= MPC52xx_PSC_IMR_TXRDY;
@@ -485,7 +485,7 @@ mpc52xx_uart_int_tx_chars(struct uart_port *port)
485 485
486 /* Nothing to do ? */ 486 /* Nothing to do ? */
487 if (uart_circ_empty(xmit) || uart_tx_stopped(port)) { 487 if (uart_circ_empty(xmit) || uart_tx_stopped(port)) {
488 mpc52xx_uart_stop_tx(port,0); 488 mpc52xx_uart_stop_tx(port);
489 return 0; 489 return 0;
490 } 490 }
491 491
@@ -504,7 +504,7 @@ mpc52xx_uart_int_tx_chars(struct uart_port *port)
504 504
505 /* Maybe we're done after all */ 505 /* Maybe we're done after all */
506 if (uart_circ_empty(xmit)) { 506 if (uart_circ_empty(xmit)) {
507 mpc52xx_uart_stop_tx(port,0); 507 mpc52xx_uart_stop_tx(port);
508 return 0; 508 return 0;
509 } 509 }
510 510
diff --git a/drivers/serial/mpsc.c b/drivers/serial/mpsc.c
index e43276c6a954..efe79b1fd431 100644
--- a/drivers/serial/mpsc.c
+++ b/drivers/serial/mpsc.c
@@ -1072,18 +1072,18 @@ mpsc_get_mctrl(struct uart_port *port)
1072} 1072}
1073 1073
1074static void 1074static void
1075mpsc_stop_tx(struct uart_port *port, uint tty_start) 1075mpsc_stop_tx(struct uart_port *port)
1076{ 1076{
1077 struct mpsc_port_info *pi = (struct mpsc_port_info *)port; 1077 struct mpsc_port_info *pi = (struct mpsc_port_info *)port;
1078 1078
1079 pr_debug("mpsc_stop_tx[%d]: tty_start: %d\n", port->line, tty_start); 1079 pr_debug("mpsc_stop_tx[%d]\n", port->line);
1080 1080
1081 mpsc_freeze(pi); 1081 mpsc_freeze(pi);
1082 return; 1082 return;
1083} 1083}
1084 1084
1085static void 1085static void
1086mpsc_start_tx(struct uart_port *port, uint tty_start) 1086mpsc_start_tx(struct uart_port *port)
1087{ 1087{
1088 struct mpsc_port_info *pi = (struct mpsc_port_info *)port; 1088 struct mpsc_port_info *pi = (struct mpsc_port_info *)port;
1089 1089
@@ -1091,7 +1091,7 @@ mpsc_start_tx(struct uart_port *port, uint tty_start)
1091 mpsc_copy_tx_data(pi); 1091 mpsc_copy_tx_data(pi);
1092 mpsc_sdma_start_tx(pi); 1092 mpsc_sdma_start_tx(pi);
1093 1093
1094 pr_debug("mpsc_start_tx[%d]: tty_start: %d\n", port->line, tty_start); 1094 pr_debug("mpsc_start_tx[%d]\n", port->line);
1095 return; 1095 return;
1096} 1096}
1097 1097
diff --git a/drivers/serial/mux.c b/drivers/serial/mux.c
index dadd7e19714e..189064607709 100644
--- a/drivers/serial/mux.c
+++ b/drivers/serial/mux.c
@@ -111,22 +111,20 @@ static unsigned int mux_get_mctrl(struct uart_port *port)
111/** 111/**
112 * mux_stop_tx - Stop transmitting characters. 112 * mux_stop_tx - Stop transmitting characters.
113 * @port: Ptr to the uart_port. 113 * @port: Ptr to the uart_port.
114 * @tty_stop: tty layer issue this command?
115 * 114 *
116 * The Serial MUX does not support this function. 115 * The Serial MUX does not support this function.
117 */ 116 */
118static void mux_stop_tx(struct uart_port *port, unsigned int tty_stop) 117static void mux_stop_tx(struct uart_port *port)
119{ 118{
120} 119}
121 120
122/** 121/**
123 * mux_start_tx - Start transmitting characters. 122 * mux_start_tx - Start transmitting characters.
124 * @port: Ptr to the uart_port. 123 * @port: Ptr to the uart_port.
125 * @tty_start: tty layer issue this command?
126 * 124 *
127 * The Serial Mux does not support this function. 125 * The Serial Mux does not support this function.
128 */ 126 */
129static void mux_start_tx(struct uart_port *port, unsigned int tty_start) 127static void mux_start_tx(struct uart_port *port)
130{ 128{
131} 129}
132 130
@@ -181,7 +179,7 @@ static void mux_write(struct uart_port *port)
181 } 179 }
182 180
183 if(uart_circ_empty(xmit) || uart_tx_stopped(port)) { 181 if(uart_circ_empty(xmit) || uart_tx_stopped(port)) {
184 mux_stop_tx(port, 0); 182 mux_stop_tx(port);
185 return; 183 return;
186 } 184 }
187 185
@@ -202,7 +200,7 @@ static void mux_write(struct uart_port *port)
202 uart_write_wakeup(port); 200 uart_write_wakeup(port);
203 201
204 if (uart_circ_empty(xmit)) 202 if (uart_circ_empty(xmit))
205 mux_stop_tx(port, 0); 203 mux_stop_tx(port);
206} 204}
207 205
208/** 206/**
diff --git a/drivers/serial/pmac_zilog.c b/drivers/serial/pmac_zilog.c
index 7db2f37532cf..5bfde99e245e 100644
--- a/drivers/serial/pmac_zilog.c
+++ b/drivers/serial/pmac_zilog.c
@@ -630,11 +630,10 @@ static unsigned int pmz_get_mctrl(struct uart_port *port)
630 630
631/* 631/*
632 * Stop TX side. Dealt like sunzilog at next Tx interrupt, 632 * Stop TX side. Dealt like sunzilog at next Tx interrupt,
633 * though for DMA, we will have to do a bit more. What is 633 * though for DMA, we will have to do a bit more.
634 * the meaning of the tty_stop bit ? XXX
635 * The port lock is held and interrupts are disabled. 634 * The port lock is held and interrupts are disabled.
636 */ 635 */
637static void pmz_stop_tx(struct uart_port *port, unsigned int tty_stop) 636static void pmz_stop_tx(struct uart_port *port)
638{ 637{
639 to_pmz(port)->flags |= PMACZILOG_FLAG_TX_STOPPED; 638 to_pmz(port)->flags |= PMACZILOG_FLAG_TX_STOPPED;
640} 639}
@@ -643,7 +642,7 @@ static void pmz_stop_tx(struct uart_port *port, unsigned int tty_stop)
643 * Kick the Tx side. 642 * Kick the Tx side.
644 * The port lock is held and interrupts are disabled. 643 * The port lock is held and interrupts are disabled.
645 */ 644 */
646static void pmz_start_tx(struct uart_port *port, unsigned int tty_start) 645static void pmz_start_tx(struct uart_port *port)
647{ 646{
648 struct uart_pmac_port *uap = to_pmz(port); 647 struct uart_pmac_port *uap = to_pmz(port);
649 unsigned char status; 648 unsigned char status;
diff --git a/drivers/serial/pxa.c b/drivers/serial/pxa.c
index 461c81c93207..eaa0af835290 100644
--- a/drivers/serial/pxa.c
+++ b/drivers/serial/pxa.c
@@ -80,7 +80,7 @@ static void serial_pxa_enable_ms(struct uart_port *port)
80 serial_out(up, UART_IER, up->ier); 80 serial_out(up, UART_IER, up->ier);
81} 81}
82 82
83static void serial_pxa_stop_tx(struct uart_port *port, unsigned int tty_stop) 83static void serial_pxa_stop_tx(struct uart_port *port)
84{ 84{
85 struct uart_pxa_port *up = (struct uart_pxa_port *)port; 85 struct uart_pxa_port *up = (struct uart_pxa_port *)port;
86 86
@@ -185,7 +185,7 @@ static void transmit_chars(struct uart_pxa_port *up)
185 return; 185 return;
186 } 186 }
187 if (uart_circ_empty(xmit) || uart_tx_stopped(&up->port)) { 187 if (uart_circ_empty(xmit) || uart_tx_stopped(&up->port)) {
188 serial_pxa_stop_tx(&up->port, 0); 188 serial_pxa_stop_tx(&up->port);
189 return; 189 return;
190 } 190 }
191 191
@@ -203,10 +203,10 @@ static void transmit_chars(struct uart_pxa_port *up)
203 203
204 204
205 if (uart_circ_empty(xmit)) 205 if (uart_circ_empty(xmit))
206 serial_pxa_stop_tx(&up->port, 0); 206 serial_pxa_stop_tx(&up->port);
207} 207}
208 208
209static void serial_pxa_start_tx(struct uart_port *port, unsigned int tty_start) 209static void serial_pxa_start_tx(struct uart_port *port)
210{ 210{
211 struct uart_pxa_port *up = (struct uart_pxa_port *)port; 211 struct uart_pxa_port *up = (struct uart_pxa_port *)port;
212 212
diff --git a/drivers/serial/s3c2410.c b/drivers/serial/s3c2410.c
index 7365d4b50b95..c361c6fb0809 100644
--- a/drivers/serial/s3c2410.c
+++ b/drivers/serial/s3c2410.c
@@ -246,8 +246,7 @@ static void s3c24xx_serial_rx_disable(struct uart_port *port)
246 spin_unlock_irqrestore(&port->lock, flags); 246 spin_unlock_irqrestore(&port->lock, flags);
247} 247}
248 248
249static void 249static void s3c24xx_serial_stop_tx(struct uart_port *port)
250s3c24xx_serial_stop_tx(struct uart_port *port, unsigned int tty_stop)
251{ 250{
252 if (tx_enabled(port)) { 251 if (tx_enabled(port)) {
253 disable_irq(TX_IRQ(port)); 252 disable_irq(TX_IRQ(port));
@@ -257,8 +256,7 @@ s3c24xx_serial_stop_tx(struct uart_port *port, unsigned int tty_stop)
257 } 256 }
258} 257}
259 258
260static void 259static void s3c24xx_serial_start_tx(struct uart_port *port)
261s3c24xx_serial_start_tx(struct uart_port *port, unsigned int tty_start)
262{ 260{
263 if (!tx_enabled(port)) { 261 if (!tx_enabled(port)) {
264 if (port->flags & UPF_CONS_FLOW) 262 if (port->flags & UPF_CONS_FLOW)
@@ -424,7 +422,7 @@ static irqreturn_t s3c24xx_serial_tx_chars(int irq, void *id, struct pt_regs *re
424 */ 422 */
425 423
426 if (uart_circ_empty(xmit) || uart_tx_stopped(port)) { 424 if (uart_circ_empty(xmit) || uart_tx_stopped(port)) {
427 s3c24xx_serial_stop_tx(port, 0); 425 s3c24xx_serial_stop_tx(port);
428 goto out; 426 goto out;
429 } 427 }
430 428
@@ -443,7 +441,7 @@ static irqreturn_t s3c24xx_serial_tx_chars(int irq, void *id, struct pt_regs *re
443 uart_write_wakeup(port); 441 uart_write_wakeup(port);
444 442
445 if (uart_circ_empty(xmit)) 443 if (uart_circ_empty(xmit))
446 s3c24xx_serial_stop_tx(port, 0); 444 s3c24xx_serial_stop_tx(port);
447 445
448 out: 446 out:
449 return IRQ_HANDLED; 447 return IRQ_HANDLED;
diff --git a/drivers/serial/sa1100.c b/drivers/serial/sa1100.c
index 98641c3f5ab9..1225b14f6e9d 100644
--- a/drivers/serial/sa1100.c
+++ b/drivers/serial/sa1100.c
@@ -145,7 +145,7 @@ static void sa1100_timeout(unsigned long data)
145/* 145/*
146 * interrupts disabled on entry 146 * interrupts disabled on entry
147 */ 147 */
148static void sa1100_stop_tx(struct uart_port *port, unsigned int tty_stop) 148static void sa1100_stop_tx(struct uart_port *port)
149{ 149{
150 struct sa1100_port *sport = (struct sa1100_port *)port; 150 struct sa1100_port *sport = (struct sa1100_port *)port;
151 u32 utcr3; 151 u32 utcr3;
@@ -158,7 +158,7 @@ static void sa1100_stop_tx(struct uart_port *port, unsigned int tty_stop)
158/* 158/*
159 * interrupts may not be disabled on entry 159 * interrupts may not be disabled on entry
160 */ 160 */
161static void sa1100_start_tx(struct uart_port *port, unsigned int tty_start) 161static void sa1100_start_tx(struct uart_port *port)
162{ 162{
163 struct sa1100_port *sport = (struct sa1100_port *)port; 163 struct sa1100_port *sport = (struct sa1100_port *)port;
164 unsigned long flags; 164 unsigned long flags;
@@ -264,7 +264,7 @@ static void sa1100_tx_chars(struct sa1100_port *sport)
264 sa1100_mctrl_check(sport); 264 sa1100_mctrl_check(sport);
265 265
266 if (uart_circ_empty(xmit) || uart_tx_stopped(&sport->port)) { 266 if (uart_circ_empty(xmit) || uart_tx_stopped(&sport->port)) {
267 sa1100_stop_tx(&sport->port, 0); 267 sa1100_stop_tx(&sport->port);
268 return; 268 return;
269 } 269 }
270 270
@@ -284,7 +284,7 @@ static void sa1100_tx_chars(struct sa1100_port *sport)
284 uart_write_wakeup(&sport->port); 284 uart_write_wakeup(&sport->port);
285 285
286 if (uart_circ_empty(xmit)) 286 if (uart_circ_empty(xmit))
287 sa1100_stop_tx(&sport->port, 0); 287 sa1100_stop_tx(&sport->port);
288} 288}
289 289
290static irqreturn_t sa1100_int(int irq, void *dev_id, struct pt_regs *regs) 290static irqreturn_t sa1100_int(int irq, void *dev_id, struct pt_regs *regs)
diff --git a/drivers/serial/serial_core.c b/drivers/serial/serial_core.c
index 54699c3a00ab..dea156a62d0a 100644
--- a/drivers/serial/serial_core.c
+++ b/drivers/serial/serial_core.c
@@ -80,7 +80,7 @@ static void uart_stop(struct tty_struct *tty)
80 unsigned long flags; 80 unsigned long flags;
81 81
82 spin_lock_irqsave(&port->lock, flags); 82 spin_lock_irqsave(&port->lock, flags);
83 port->ops->stop_tx(port, 1); 83 port->ops->stop_tx(port);
84 spin_unlock_irqrestore(&port->lock, flags); 84 spin_unlock_irqrestore(&port->lock, flags);
85} 85}
86 86
@@ -91,7 +91,7 @@ static void __uart_start(struct tty_struct *tty)
91 91
92 if (!uart_circ_empty(&state->info->xmit) && state->info->xmit.buf && 92 if (!uart_circ_empty(&state->info->xmit) && state->info->xmit.buf &&
93 !tty->stopped && !tty->hw_stopped) 93 !tty->stopped && !tty->hw_stopped)
94 port->ops->start_tx(port, 1); 94 port->ops->start_tx(port);
95} 95}
96 96
97static void uart_start(struct tty_struct *tty) 97static void uart_start(struct tty_struct *tty)
@@ -542,7 +542,7 @@ static void uart_send_xchar(struct tty_struct *tty, char ch)
542 port->x_char = ch; 542 port->x_char = ch;
543 if (ch) { 543 if (ch) {
544 spin_lock_irqsave(&port->lock, flags); 544 spin_lock_irqsave(&port->lock, flags);
545 port->ops->start_tx(port, 0); 545 port->ops->start_tx(port);
546 spin_unlock_irqrestore(&port->lock, flags); 546 spin_unlock_irqrestore(&port->lock, flags);
547 } 547 }
548 } 548 }
@@ -1146,7 +1146,7 @@ static void uart_set_termios(struct tty_struct *tty, struct termios *old_termios
1146 spin_lock_irqsave(&state->port->lock, flags); 1146 spin_lock_irqsave(&state->port->lock, flags);
1147 if (!(state->port->ops->get_mctrl(state->port) & TIOCM_CTS)) { 1147 if (!(state->port->ops->get_mctrl(state->port) & TIOCM_CTS)) {
1148 tty->hw_stopped = 1; 1148 tty->hw_stopped = 1;
1149 state->port->ops->stop_tx(state->port, 0); 1149 state->port->ops->stop_tx(state->port);
1150 } 1150 }
1151 spin_unlock_irqrestore(&state->port->lock, flags); 1151 spin_unlock_irqrestore(&state->port->lock, flags);
1152 } 1152 }
@@ -1869,7 +1869,7 @@ int uart_suspend_port(struct uart_driver *drv, struct uart_port *port)
1869 struct uart_ops *ops = port->ops; 1869 struct uart_ops *ops = port->ops;
1870 1870
1871 spin_lock_irq(&port->lock); 1871 spin_lock_irq(&port->lock);
1872 ops->stop_tx(port, 0); 1872 ops->stop_tx(port);
1873 ops->set_mctrl(port, 0); 1873 ops->set_mctrl(port, 0);
1874 ops->stop_rx(port); 1874 ops->stop_rx(port);
1875 spin_unlock_irq(&port->lock); 1875 spin_unlock_irq(&port->lock);
@@ -1935,7 +1935,7 @@ int uart_resume_port(struct uart_driver *drv, struct uart_port *port)
1935 uart_change_speed(state, NULL); 1935 uart_change_speed(state, NULL);
1936 spin_lock_irq(&port->lock); 1936 spin_lock_irq(&port->lock);
1937 ops->set_mctrl(port, port->mctrl); 1937 ops->set_mctrl(port, port->mctrl);
1938 ops->start_tx(port, 0); 1938 ops->start_tx(port);
1939 spin_unlock_irq(&port->lock); 1939 spin_unlock_irq(&port->lock);
1940 } 1940 }
1941 1941
@@ -2289,143 +2289,11 @@ int uart_match_port(struct uart_port *port1, struct uart_port *port2)
2289} 2289}
2290EXPORT_SYMBOL(uart_match_port); 2290EXPORT_SYMBOL(uart_match_port);
2291 2291
2292/*
2293 * Try to find an unused uart_state slot for a port.
2294 */
2295static struct uart_state *
2296uart_find_match_or_unused(struct uart_driver *drv, struct uart_port *port)
2297{
2298 int i;
2299
2300 /*
2301 * First, find a port entry which matches. Note: if we do
2302 * find a matching entry, and it has a non-zero use count,
2303 * then we can't register the port.
2304 */
2305 for (i = 0; i < drv->nr; i++)
2306 if (uart_match_port(drv->state[i].port, port))
2307 return &drv->state[i];
2308
2309 /*
2310 * We didn't find a matching entry, so look for the first
2311 * free entry. We look for one which hasn't been previously
2312 * used (indicated by zero iobase).
2313 */
2314 for (i = 0; i < drv->nr; i++)
2315 if (drv->state[i].port->type == PORT_UNKNOWN &&
2316 drv->state[i].port->iobase == 0 &&
2317 drv->state[i].count == 0)
2318 return &drv->state[i];
2319
2320 /*
2321 * That also failed. Last resort is to find any currently
2322 * entry which doesn't have a real port associated with it.
2323 */
2324 for (i = 0; i < drv->nr; i++)
2325 if (drv->state[i].port->type == PORT_UNKNOWN &&
2326 drv->state[i].count == 0)
2327 return &drv->state[i];
2328
2329 return NULL;
2330}
2331
2332/**
2333 * uart_register_port: register uart settings with a port
2334 * @drv: pointer to the uart low level driver structure for this port
2335 * @port: uart port structure describing the port
2336 *
2337 * Register UART settings with the specified low level driver. Detect
2338 * the type of the port if UPF_BOOT_AUTOCONF is set, and detect the
2339 * IRQ if UPF_AUTO_IRQ is set.
2340 *
2341 * We try to pick the same port for the same IO base address, so that
2342 * when a modem is plugged in, unplugged and plugged back in, it gets
2343 * allocated the same port.
2344 *
2345 * Returns negative error, or positive line number.
2346 */
2347int uart_register_port(struct uart_driver *drv, struct uart_port *port)
2348{
2349 struct uart_state *state;
2350 int ret;
2351
2352 down(&port_sem);
2353
2354 state = uart_find_match_or_unused(drv, port);
2355
2356 if (state) {
2357 /*
2358 * Ok, we've found a line that we can use.
2359 *
2360 * If we find a port that matches this one, and it appears
2361 * to be in-use (even if it doesn't have a type) we shouldn't
2362 * alter it underneath itself - the port may be open and
2363 * trying to do useful work.
2364 */
2365 if (uart_users(state) != 0) {
2366 ret = -EBUSY;
2367 goto out;
2368 }
2369
2370 /*
2371 * If the port is already initialised, don't touch it.
2372 */
2373 if (state->port->type == PORT_UNKNOWN) {
2374 state->port->iobase = port->iobase;
2375 state->port->membase = port->membase;
2376 state->port->irq = port->irq;
2377 state->port->uartclk = port->uartclk;
2378 state->port->fifosize = port->fifosize;
2379 state->port->regshift = port->regshift;
2380 state->port->iotype = port->iotype;
2381 state->port->flags = port->flags;
2382 state->port->line = state - drv->state;
2383 state->port->mapbase = port->mapbase;
2384
2385 uart_configure_port(drv, state, state->port);
2386 }
2387
2388 ret = state->port->line;
2389 } else
2390 ret = -ENOSPC;
2391 out:
2392 up(&port_sem);
2393 return ret;
2394}
2395
2396/**
2397 * uart_unregister_port - de-allocate a port
2398 * @drv: pointer to the uart low level driver structure for this port
2399 * @line: line index previously returned from uart_register_port()
2400 *
2401 * Hang up the specified line associated with the low level driver,
2402 * and mark the port as unused.
2403 */
2404void uart_unregister_port(struct uart_driver *drv, int line)
2405{
2406 struct uart_state *state;
2407
2408 if (line < 0 || line >= drv->nr) {
2409 printk(KERN_ERR "Attempt to unregister ");
2410 printk("%s%d", drv->dev_name, line);
2411 printk("\n");
2412 return;
2413 }
2414
2415 state = drv->state + line;
2416
2417 down(&port_sem);
2418 uart_unconfigure_port(drv, state);
2419 up(&port_sem);
2420}
2421
2422EXPORT_SYMBOL(uart_write_wakeup); 2292EXPORT_SYMBOL(uart_write_wakeup);
2423EXPORT_SYMBOL(uart_register_driver); 2293EXPORT_SYMBOL(uart_register_driver);
2424EXPORT_SYMBOL(uart_unregister_driver); 2294EXPORT_SYMBOL(uart_unregister_driver);
2425EXPORT_SYMBOL(uart_suspend_port); 2295EXPORT_SYMBOL(uart_suspend_port);
2426EXPORT_SYMBOL(uart_resume_port); 2296EXPORT_SYMBOL(uart_resume_port);
2427EXPORT_SYMBOL(uart_register_port);
2428EXPORT_SYMBOL(uart_unregister_port);
2429EXPORT_SYMBOL(uart_add_one_port); 2297EXPORT_SYMBOL(uart_add_one_port);
2430EXPORT_SYMBOL(uart_remove_one_port); 2298EXPORT_SYMBOL(uart_remove_one_port);
2431 2299
diff --git a/drivers/serial/serial_lh7a40x.c b/drivers/serial/serial_lh7a40x.c
index 56f269b6bfb1..32f808d157a1 100644
--- a/drivers/serial/serial_lh7a40x.c
+++ b/drivers/serial/serial_lh7a40x.c
@@ -112,13 +112,12 @@ struct uart_port_lh7a40x {
112 unsigned int statusPrev; /* Most recently read modem status */ 112 unsigned int statusPrev; /* Most recently read modem status */
113}; 113};
114 114
115static void lh7a40xuart_stop_tx (struct uart_port* port, unsigned int tty_stop) 115static void lh7a40xuart_stop_tx (struct uart_port* port)
116{ 116{
117 BIT_CLR (port, UART_R_INTEN, TxInt); 117 BIT_CLR (port, UART_R_INTEN, TxInt);
118} 118}
119 119
120static void lh7a40xuart_start_tx (struct uart_port* port, 120static void lh7a40xuart_start_tx (struct uart_port* port)
121 unsigned int tty_start)
122{ 121{
123 BIT_SET (port, UART_R_INTEN, TxInt); 122 BIT_SET (port, UART_R_INTEN, TxInt);
124 123
diff --git a/drivers/serial/serial_txx9.c b/drivers/serial/serial_txx9.c
index d085030df70b..49afadbe461b 100644
--- a/drivers/serial/serial_txx9.c
+++ b/drivers/serial/serial_txx9.c
@@ -253,7 +253,7 @@ sio_quot_set(struct uart_txx9_port *up, int quot)
253 sio_out(up, TXX9_SIBGR, 0xff | TXX9_SIBGR_BCLK_T6); 253 sio_out(up, TXX9_SIBGR, 0xff | TXX9_SIBGR_BCLK_T6);
254} 254}
255 255
256static void serial_txx9_stop_tx(struct uart_port *port, unsigned int tty_stop) 256static void serial_txx9_stop_tx(struct uart_port *port)
257{ 257{
258 struct uart_txx9_port *up = (struct uart_txx9_port *)port; 258 struct uart_txx9_port *up = (struct uart_txx9_port *)port;
259 unsigned long flags; 259 unsigned long flags;
@@ -263,7 +263,7 @@ static void serial_txx9_stop_tx(struct uart_port *port, unsigned int tty_stop)
263 spin_unlock_irqrestore(&up->port.lock, flags); 263 spin_unlock_irqrestore(&up->port.lock, flags);
264} 264}
265 265
266static void serial_txx9_start_tx(struct uart_port *port, unsigned int tty_start) 266static void serial_txx9_start_tx(struct uart_port *port)
267{ 267{
268 struct uart_txx9_port *up = (struct uart_txx9_port *)port; 268 struct uart_txx9_port *up = (struct uart_txx9_port *)port;
269 unsigned long flags; 269 unsigned long flags;
@@ -372,7 +372,7 @@ static inline void transmit_chars(struct uart_txx9_port *up)
372 return; 372 return;
373 } 373 }
374 if (uart_circ_empty(xmit) || uart_tx_stopped(&up->port)) { 374 if (uart_circ_empty(xmit) || uart_tx_stopped(&up->port)) {
375 serial_txx9_stop_tx(&up->port, 0); 375 serial_txx9_stop_tx(&up->port);
376 return; 376 return;
377 } 377 }
378 378
@@ -389,7 +389,7 @@ static inline void transmit_chars(struct uart_txx9_port *up)
389 uart_write_wakeup(&up->port); 389 uart_write_wakeup(&up->port);
390 390
391 if (uart_circ_empty(xmit)) 391 if (uart_circ_empty(xmit))
392 serial_txx9_stop_tx(&up->port, 0); 392 serial_txx9_stop_tx(&up->port);
393} 393}
394 394
395static irqreturn_t serial_txx9_interrupt(int irq, void *dev_id, struct pt_regs *regs) 395static irqreturn_t serial_txx9_interrupt(int irq, void *dev_id, struct pt_regs *regs)
diff --git a/drivers/serial/sh-sci.c b/drivers/serial/sh-sci.c
index ad5b776d779b..512266307866 100644
--- a/drivers/serial/sh-sci.c
+++ b/drivers/serial/sh-sci.c
@@ -79,8 +79,8 @@ static struct sci_port *serial_console_port = 0;
79#endif /* CONFIG_SERIAL_SH_SCI_CONSOLE */ 79#endif /* CONFIG_SERIAL_SH_SCI_CONSOLE */
80 80
81/* Function prototypes */ 81/* Function prototypes */
82static void sci_stop_tx(struct uart_port *port, unsigned int tty_stop); 82static void sci_stop_tx(struct uart_port *port);
83static void sci_start_tx(struct uart_port *port, unsigned int tty_start); 83static void sci_start_tx(struct uart_port *port);
84static void sci_start_rx(struct uart_port *port, unsigned int tty_start); 84static void sci_start_rx(struct uart_port *port, unsigned int tty_start);
85static void sci_stop_rx(struct uart_port *port); 85static void sci_stop_rx(struct uart_port *port);
86static int sci_request_irq(struct sci_port *port); 86static int sci_request_irq(struct sci_port *port);
@@ -455,7 +455,7 @@ static void sci_transmit_chars(struct uart_port *port)
455 if (uart_circ_chars_pending(xmit) < WAKEUP_CHARS) 455 if (uart_circ_chars_pending(xmit) < WAKEUP_CHARS)
456 uart_write_wakeup(port); 456 uart_write_wakeup(port);
457 if (uart_circ_empty(xmit)) { 457 if (uart_circ_empty(xmit)) {
458 sci_stop_tx(port, 0); 458 sci_stop_tx(port);
459 } else { 459 } else {
460 local_irq_save(flags); 460 local_irq_save(flags);
461 ctrl = sci_in(port, SCSCR); 461 ctrl = sci_in(port, SCSCR);
@@ -900,7 +900,7 @@ static unsigned int sci_get_mctrl(struct uart_port *port)
900 return TIOCM_DTR | TIOCM_RTS | TIOCM_DSR; 900 return TIOCM_DTR | TIOCM_RTS | TIOCM_DSR;
901} 901}
902 902
903static void sci_start_tx(struct uart_port *port, unsigned int tty_start) 903static void sci_start_tx(struct uart_port *port)
904{ 904{
905 struct sci_port *s = &sci_ports[port->line]; 905 struct sci_port *s = &sci_ports[port->line];
906 906
@@ -909,7 +909,7 @@ static void sci_start_tx(struct uart_port *port, unsigned int tty_start)
909 enable_irq(s->irqs[SCIx_TXI_IRQ]); 909 enable_irq(s->irqs[SCIx_TXI_IRQ]);
910} 910}
911 911
912static void sci_stop_tx(struct uart_port *port, unsigned int tty_stop) 912static void sci_stop_tx(struct uart_port *port)
913{ 913{
914 unsigned long flags; 914 unsigned long flags;
915 unsigned short ctrl; 915 unsigned short ctrl;
@@ -978,7 +978,7 @@ static void sci_shutdown(struct uart_port *port)
978 struct sci_port *s = &sci_ports[port->line]; 978 struct sci_port *s = &sci_ports[port->line];
979 979
980 sci_stop_rx(port); 980 sci_stop_rx(port);
981 sci_stop_tx(port, 1); 981 sci_stop_tx(port);
982 sci_free_irq(s); 982 sci_free_irq(s);
983 983
984#if defined(__H8300S__) 984#if defined(__H8300S__)
diff --git a/drivers/serial/sn_console.c b/drivers/serial/sn_console.c
index 12d1f14e78ce..313f9df24a2d 100644
--- a/drivers/serial/sn_console.c
+++ b/drivers/serial/sn_console.c
@@ -259,10 +259,9 @@ static unsigned int snp_tx_empty(struct uart_port *port)
259/** 259/**
260 * snp_stop_tx - stop the transmitter - no-op for us 260 * snp_stop_tx - stop the transmitter - no-op for us
261 * @port: Port to operat eon - we ignore - no-op function 261 * @port: Port to operat eon - we ignore - no-op function
262 * @tty_stop: Set to 1 if called via uart_stop
263 * 262 *
264 */ 263 */
265static void snp_stop_tx(struct uart_port *port, unsigned int tty_stop) 264static void snp_stop_tx(struct uart_port *port)
266{ 265{
267} 266}
268 267
@@ -325,10 +324,9 @@ static void snp_stop_rx(struct uart_port *port)
325/** 324/**
326 * snp_start_tx - Start transmitter 325 * snp_start_tx - Start transmitter
327 * @port: Port to operate on 326 * @port: Port to operate on
328 * @tty_stop: Set to 1 if called via uart_start
329 * 327 *
330 */ 328 */
331static void snp_start_tx(struct uart_port *port, unsigned int tty_stop) 329static void snp_start_tx(struct uart_port *port)
332{ 330{
333 if (sal_console_port.sc_ops->sal_wakeup_transmit) 331 if (sal_console_port.sc_ops->sal_wakeup_transmit)
334 sal_console_port.sc_ops->sal_wakeup_transmit(&sal_console_port, 332 sal_console_port.sc_ops->sal_wakeup_transmit(&sal_console_port,
@@ -615,7 +613,7 @@ static void sn_transmit_chars(struct sn_cons_port *port, int raw)
615 uart_write_wakeup(&port->sc_port); 613 uart_write_wakeup(&port->sc_port);
616 614
617 if (uart_circ_empty(xmit)) 615 if (uart_circ_empty(xmit))
618 snp_stop_tx(&port->sc_port, 0); /* no-op for us */ 616 snp_stop_tx(&port->sc_port); /* no-op for us */
619} 617}
620 618
621/** 619/**
diff --git a/drivers/serial/sunsab.c b/drivers/serial/sunsab.c
index 8d198880756a..e971156daa60 100644
--- a/drivers/serial/sunsab.c
+++ b/drivers/serial/sunsab.c
@@ -245,7 +245,7 @@ receive_chars(struct uart_sunsab_port *up,
245 return tty; 245 return tty;
246} 246}
247 247
248static void sunsab_stop_tx(struct uart_port *, unsigned int); 248static void sunsab_stop_tx(struct uart_port *);
249static void sunsab_tx_idle(struct uart_sunsab_port *); 249static void sunsab_tx_idle(struct uart_sunsab_port *);
250 250
251static void transmit_chars(struct uart_sunsab_port *up, 251static void transmit_chars(struct uart_sunsab_port *up,
@@ -301,7 +301,7 @@ static void transmit_chars(struct uart_sunsab_port *up,
301 uart_write_wakeup(&up->port); 301 uart_write_wakeup(&up->port);
302 302
303 if (uart_circ_empty(xmit)) 303 if (uart_circ_empty(xmit))
304 sunsab_stop_tx(&up->port, 0); 304 sunsab_stop_tx(&up->port);
305} 305}
306 306
307static void check_status(struct uart_sunsab_port *up, 307static void check_status(struct uart_sunsab_port *up,
@@ -448,7 +448,7 @@ static unsigned int sunsab_get_mctrl(struct uart_port *port)
448} 448}
449 449
450/* port->lock held by caller. */ 450/* port->lock held by caller. */
451static void sunsab_stop_tx(struct uart_port *port, unsigned int tty_stop) 451static void sunsab_stop_tx(struct uart_port *port)
452{ 452{
453 struct uart_sunsab_port *up = (struct uart_sunsab_port *) port; 453 struct uart_sunsab_port *up = (struct uart_sunsab_port *) port;
454 454
@@ -476,7 +476,7 @@ static void sunsab_tx_idle(struct uart_sunsab_port *up)
476} 476}
477 477
478/* port->lock held by caller. */ 478/* port->lock held by caller. */
479static void sunsab_start_tx(struct uart_port *port, unsigned int tty_start) 479static void sunsab_start_tx(struct uart_port *port)
480{ 480{
481 struct uart_sunsab_port *up = (struct uart_sunsab_port *) port; 481 struct uart_sunsab_port *up = (struct uart_sunsab_port *) port;
482 struct circ_buf *xmit = &up->port.info->xmit; 482 struct circ_buf *xmit = &up->port.info->xmit;
diff --git a/drivers/serial/sunsu.c b/drivers/serial/sunsu.c
index d57a3553aea3..0cc879eb1c02 100644
--- a/drivers/serial/sunsu.c
+++ b/drivers/serial/sunsu.c
@@ -255,21 +255,27 @@ static void disable_rsa(struct uart_sunsu_port *up)
255} 255}
256#endif /* CONFIG_SERIAL_8250_RSA */ 256#endif /* CONFIG_SERIAL_8250_RSA */
257 257
258static void sunsu_stop_tx(struct uart_port *port, unsigned int tty_stop) 258static inline void __stop_tx(struct uart_sunsu_port *p)
259{
260 if (p->ier & UART_IER_THRI) {
261 p->ier &= ~UART_IER_THRI;
262 serial_out(p, UART_IER, p->ier);
263 }
264}
265
266static void sunsu_stop_tx(struct uart_port *port)
259{ 267{
260 struct uart_sunsu_port *up = (struct uart_sunsu_port *) port; 268 struct uart_sunsu_port *up = (struct uart_sunsu_port *) port;
261 269
262 if (up->ier & UART_IER_THRI) { 270 __stop_tx(up);
263 up->ier &= ~UART_IER_THRI; 271
264 serial_out(up, UART_IER, up->ier); 272 if (up->port.type == PORT_16C950 && tty_stop /*FIXME*/) {
265 }
266 if (up->port.type == PORT_16C950 && tty_stop) {
267 up->acr |= UART_ACR_TXDIS; 273 up->acr |= UART_ACR_TXDIS;
268 serial_icr_write(up, UART_ACR, up->acr); 274 serial_icr_write(up, UART_ACR, up->acr);
269 } 275 }
270} 276}
271 277
272static void sunsu_start_tx(struct uart_port *port, unsigned int tty_start) 278static void sunsu_start_tx(struct uart_port *port)
273{ 279{
274 struct uart_sunsu_port *up = (struct uart_sunsu_port *) port; 280 struct uart_sunsu_port *up = (struct uart_sunsu_port *) port;
275 281
@@ -280,7 +286,7 @@ static void sunsu_start_tx(struct uart_port *port, unsigned int tty_start)
280 /* 286 /*
281 * We only do this from uart_start 287 * We only do this from uart_start
282 */ 288 */
283 if (tty_start && up->port.type == PORT_16C950) { 289 if (tty_start && up->port.type == PORT_16C950 /*FIXME*/) {
284 up->acr &= ~UART_ACR_TXDIS; 290 up->acr &= ~UART_ACR_TXDIS;
285 serial_icr_write(up, UART_ACR, up->acr); 291 serial_icr_write(up, UART_ACR, up->acr);
286 } 292 }
@@ -413,8 +419,12 @@ static _INLINE_ void transmit_chars(struct uart_sunsu_port *up)
413 up->port.x_char = 0; 419 up->port.x_char = 0;
414 return; 420 return;
415 } 421 }
416 if (uart_circ_empty(xmit) || uart_tx_stopped(&up->port)) { 422 if (uart_tx_stopped(&up->port)) {
417 sunsu_stop_tx(&up->port, 0); 423 sunsu_stop_tx(&up->port);
424 return;
425 }
426 if (uart_circ_empty(xmit)) {
427 __stop_tx(up);
418 return; 428 return;
419 } 429 }
420 430
@@ -431,7 +441,7 @@ static _INLINE_ void transmit_chars(struct uart_sunsu_port *up)
431 uart_write_wakeup(&up->port); 441 uart_write_wakeup(&up->port);
432 442
433 if (uart_circ_empty(xmit)) 443 if (uart_circ_empty(xmit))
434 sunsu_stop_tx(&up->port, 0); 444 __stop_tx(up);
435} 445}
436 446
437static _INLINE_ void check_modem_status(struct uart_sunsu_port *up) 447static _INLINE_ void check_modem_status(struct uart_sunsu_port *up)
diff --git a/drivers/serial/sunzilog.c b/drivers/serial/sunzilog.c
index bff42a7b89d0..d75445738c88 100644
--- a/drivers/serial/sunzilog.c
+++ b/drivers/serial/sunzilog.c
@@ -684,7 +684,7 @@ static void sunzilog_set_mctrl(struct uart_port *port, unsigned int mctrl)
684} 684}
685 685
686/* The port lock is held and interrupts are disabled. */ 686/* The port lock is held and interrupts are disabled. */
687static void sunzilog_stop_tx(struct uart_port *port, unsigned int tty_stop) 687static void sunzilog_stop_tx(struct uart_port *port)
688{ 688{
689 struct uart_sunzilog_port *up = (struct uart_sunzilog_port *) port; 689 struct uart_sunzilog_port *up = (struct uart_sunzilog_port *) port;
690 690
@@ -692,7 +692,7 @@ static void sunzilog_stop_tx(struct uart_port *port, unsigned int tty_stop)
692} 692}
693 693
694/* The port lock is held and interrupts are disabled. */ 694/* The port lock is held and interrupts are disabled. */
695static void sunzilog_start_tx(struct uart_port *port, unsigned int tty_start) 695static void sunzilog_start_tx(struct uart_port *port)
696{ 696{
697 struct uart_sunzilog_port *up = (struct uart_sunzilog_port *) port; 697 struct uart_sunzilog_port *up = (struct uart_sunzilog_port *) port;
698 struct zilog_channel __iomem *channel = ZILOG_CHANNEL_FROM_PORT(port); 698 struct zilog_channel __iomem *channel = ZILOG_CHANNEL_FROM_PORT(port);
diff --git a/drivers/serial/uart00.c b/drivers/serial/uart00.c
index 186f1300cead..47b504ff38b2 100644
--- a/drivers/serial/uart00.c
+++ b/drivers/serial/uart00.c
@@ -87,7 +87,7 @@
87#define UART_TX_READY(s) (((s) & UART_TSR_TX_LEVEL_MSK) < 15) 87#define UART_TX_READY(s) (((s) & UART_TSR_TX_LEVEL_MSK) < 15)
88//#define UART_TX_EMPTY(p) ((UART_GET_FR(p) & UART00_UARTFR_TMSK) == 0) 88//#define UART_TX_EMPTY(p) ((UART_GET_FR(p) & UART00_UARTFR_TMSK) == 0)
89 89
90static void uart00_stop_tx(struct uart_port *port, unsigned int tty_stop) 90static void uart00_stop_tx(struct uart_port *port)
91{ 91{
92 UART_PUT_IEC(port, UART_IEC_TIE_MSK); 92 UART_PUT_IEC(port, UART_IEC_TIE_MSK);
93} 93}
@@ -199,7 +199,7 @@ static void uart00_tx_chars(struct uart_port *port)
199 return; 199 return;
200 } 200 }
201 if (uart_circ_empty(xmit) || uart_tx_stopped(port)) { 201 if (uart_circ_empty(xmit) || uart_tx_stopped(port)) {
202 uart00_stop_tx(port, 0); 202 uart00_stop_tx(port);
203 return; 203 return;
204 } 204 }
205 205
@@ -218,10 +218,10 @@ static void uart00_tx_chars(struct uart_port *port)
218 uart_write_wakeup(port); 218 uart_write_wakeup(port);
219 219
220 if (uart_circ_empty(xmit)) 220 if (uart_circ_empty(xmit))
221 uart00_stop_tx(port, 0); 221 uart00_stop_tx(port);
222} 222}
223 223
224static void uart00_start_tx(struct uart_port *port, unsigned int tty_start) 224static void uart00_start_tx(struct uart_port *port)
225{ 225{
226 UART_PUT_IES(port, UART_IES_TIE_MSK); 226 UART_PUT_IES(port, UART_IES_TIE_MSK);
227 uart00_tx_chars(port); 227 uart00_tx_chars(port);
diff --git a/drivers/serial/v850e_uart.c b/drivers/serial/v850e_uart.c
index bb482780a41d..9378895a8d56 100644
--- a/drivers/serial/v850e_uart.c
+++ b/drivers/serial/v850e_uart.c
@@ -240,7 +240,7 @@ console_initcall(v850e_uart_console_init);
240 240
241/* TX/RX interrupt handlers. */ 241/* TX/RX interrupt handlers. */
242 242
243static void v850e_uart_stop_tx (struct uart_port *port, unsigned tty_stop); 243static void v850e_uart_stop_tx (struct uart_port *port);
244 244
245void v850e_uart_tx (struct uart_port *port) 245void v850e_uart_tx (struct uart_port *port)
246{ 246{
@@ -339,14 +339,14 @@ static unsigned v850e_uart_get_mctrl (struct uart_port *port)
339 return mctrl; 339 return mctrl;
340} 340}
341 341
342static void v850e_uart_start_tx (struct uart_port *port, unsigned tty_start) 342static void v850e_uart_start_tx (struct uart_port *port)
343{ 343{
344 v850e_intc_disable_irq (V850E_UART_TX_IRQ (port->line)); 344 v850e_intc_disable_irq (V850E_UART_TX_IRQ (port->line));
345 v850e_uart_tx (port); 345 v850e_uart_tx (port);
346 v850e_intc_enable_irq (V850E_UART_TX_IRQ (port->line)); 346 v850e_intc_enable_irq (V850E_UART_TX_IRQ (port->line));
347} 347}
348 348
349static void v850e_uart_stop_tx (struct uart_port *port, unsigned tty_stop) 349static void v850e_uart_stop_tx (struct uart_port *port)
350{ 350{
351 v850e_intc_disable_irq (V850E_UART_TX_IRQ (port->line)); 351 v850e_intc_disable_irq (V850E_UART_TX_IRQ (port->line));
352} 352}
diff --git a/drivers/serial/vr41xx_siu.c b/drivers/serial/vr41xx_siu.c
index 1f985327b0d4..0c5d65a08f6e 100644
--- a/drivers/serial/vr41xx_siu.c
+++ b/drivers/serial/vr41xx_siu.c
@@ -284,7 +284,7 @@ static unsigned int siu_get_mctrl(struct uart_port *port)
284 return mctrl; 284 return mctrl;
285} 285}
286 286
287static void siu_stop_tx(struct uart_port *port, unsigned int tty_stop) 287static void siu_stop_tx(struct uart_port *port)
288{ 288{
289 unsigned long flags; 289 unsigned long flags;
290 uint8_t ier; 290 uint8_t ier;
@@ -298,7 +298,7 @@ static void siu_stop_tx(struct uart_port *port, unsigned int tty_stop)
298 spin_unlock_irqrestore(&port->lock, flags); 298 spin_unlock_irqrestore(&port->lock, flags);
299} 299}
300 300
301static void siu_start_tx(struct uart_port *port, unsigned int tty_start) 301static void siu_start_tx(struct uart_port *port)
302{ 302{
303 unsigned long flags; 303 unsigned long flags;
304 uint8_t ier; 304 uint8_t ier;
@@ -458,7 +458,7 @@ static inline void transmit_chars(struct uart_port *port)
458 } 458 }
459 459
460 if (uart_circ_empty(xmit) || uart_tx_stopped(port)) { 460 if (uart_circ_empty(xmit) || uart_tx_stopped(port)) {
461 siu_stop_tx(port, 0); 461 siu_stop_tx(port);
462 return; 462 return;
463 } 463 }
464 464
@@ -474,7 +474,7 @@ static inline void transmit_chars(struct uart_port *port)
474 uart_write_wakeup(port); 474 uart_write_wakeup(port);
475 475
476 if (uart_circ_empty(xmit)) 476 if (uart_circ_empty(xmit))
477 siu_stop_tx(port, 0); 477 siu_stop_tx(port);
478} 478}
479 479
480static irqreturn_t siu_interrupt(int irq, void *dev_id, struct pt_regs *regs) 480static irqreturn_t siu_interrupt(int irq, void *dev_id, struct pt_regs *regs)
diff --git a/drivers/usb/net/Makefile b/drivers/usb/net/Makefile
index 16f352195512..fe3fd4115e1e 100644
--- a/drivers/usb/net/Makefile
+++ b/drivers/usb/net/Makefile
@@ -8,5 +8,3 @@ obj-$(CONFIG_USB_PEGASUS) += pegasus.o
8obj-$(CONFIG_USB_RTL8150) += rtl8150.o 8obj-$(CONFIG_USB_RTL8150) += rtl8150.o
9obj-$(CONFIG_USB_USBNET) += usbnet.o 9obj-$(CONFIG_USB_USBNET) += usbnet.o
10obj-$(CONFIG_USB_ZD1201) += zd1201.o 10obj-$(CONFIG_USB_ZD1201) += zd1201.o
11
12CFLAGS_zd1201.o = -Idrivers/net/wireless/
diff --git a/drivers/usb/net/usbnet.c b/drivers/usb/net/usbnet.c
index 4528a00c45b0..a2f67245f6da 100644
--- a/drivers/usb/net/usbnet.c
+++ b/drivers/usb/net/usbnet.c
@@ -2903,19 +2903,18 @@ static struct net_device_stats *usbnet_get_stats (struct net_device *net)
2903 * completion callbacks. 2.5 should have fixed those bugs... 2903 * completion callbacks. 2.5 should have fixed those bugs...
2904 */ 2904 */
2905 2905
2906static void defer_bh (struct usbnet *dev, struct sk_buff *skb) 2906static void defer_bh(struct usbnet *dev, struct sk_buff *skb, struct sk_buff_head *list)
2907{ 2907{
2908 struct sk_buff_head *list = skb->list;
2909 unsigned long flags; 2908 unsigned long flags;
2910 2909
2911 spin_lock_irqsave (&list->lock, flags); 2910 spin_lock_irqsave(&list->lock, flags);
2912 __skb_unlink (skb, list); 2911 __skb_unlink(skb, list);
2913 spin_unlock (&list->lock); 2912 spin_unlock(&list->lock);
2914 spin_lock (&dev->done.lock); 2913 spin_lock(&dev->done.lock);
2915 __skb_queue_tail (&dev->done, skb); 2914 __skb_queue_tail(&dev->done, skb);
2916 if (dev->done.qlen == 1) 2915 if (dev->done.qlen == 1)
2917 tasklet_schedule (&dev->bh); 2916 tasklet_schedule(&dev->bh);
2918 spin_unlock_irqrestore (&dev->done.lock, flags); 2917 spin_unlock_irqrestore(&dev->done.lock, flags);
2919} 2918}
2920 2919
2921/* some work can't be done in tasklets, so we use keventd 2920/* some work can't be done in tasklets, so we use keventd
@@ -3120,7 +3119,7 @@ block:
3120 break; 3119 break;
3121 } 3120 }
3122 3121
3123 defer_bh (dev, skb); 3122 defer_bh(dev, skb, &dev->rxq);
3124 3123
3125 if (urb) { 3124 if (urb) {
3126 if (netif_running (dev->net) 3125 if (netif_running (dev->net)
@@ -3490,7 +3489,7 @@ static void tx_complete (struct urb *urb, struct pt_regs *regs)
3490 3489
3491 urb->dev = NULL; 3490 urb->dev = NULL;
3492 entry->state = tx_done; 3491 entry->state = tx_done;
3493 defer_bh (dev, skb); 3492 defer_bh(dev, skb, &dev->txq);
3494} 3493}
3495 3494
3496/*-------------------------------------------------------------------------*/ 3495/*-------------------------------------------------------------------------*/
diff --git a/drivers/usb/net/zd1201.c b/drivers/usb/net/zd1201.c
index e32a80b39182..fc013978837e 100644
--- a/drivers/usb/net/zd1201.c
+++ b/drivers/usb/net/zd1201.c
@@ -21,7 +21,7 @@
21#include <linux/string.h> 21#include <linux/string.h>
22#include <linux/if_arp.h> 22#include <linux/if_arp.h>
23#include <linux/firmware.h> 23#include <linux/firmware.h>
24#include <ieee802_11.h> 24#include <net/ieee80211.h>
25#include "zd1201.h" 25#include "zd1201.h"
26 26
27static struct usb_device_id zd1201_table[] = { 27static struct usb_device_id zd1201_table[] = {
@@ -338,24 +338,24 @@ static void zd1201_usbrx(struct urb *urb, struct pt_regs *regs)
338 goto resubmit; 338 goto resubmit;
339 } 339 }
340 340
341 if ((seq & IEEE802_11_SCTL_FRAG) || 341 if ((seq & IEEE80211_SCTL_FRAG) ||
342 (fc & IEEE802_11_FCTL_MOREFRAGS)) { 342 (fc & IEEE80211_FCTL_MOREFRAGS)) {
343 struct zd1201_frag *frag = NULL; 343 struct zd1201_frag *frag = NULL;
344 char *ptr; 344 char *ptr;
345 345
346 if (datalen<14) 346 if (datalen<14)
347 goto resubmit; 347 goto resubmit;
348 if ((seq & IEEE802_11_SCTL_FRAG) == 0) { 348 if ((seq & IEEE80211_SCTL_FRAG) == 0) {
349 frag = kmalloc(sizeof(*frag), GFP_ATOMIC); 349 frag = kmalloc(sizeof(*frag), GFP_ATOMIC);
350 if (!frag) 350 if (!frag)
351 goto resubmit; 351 goto resubmit;
352 skb = dev_alloc_skb(IEEE802_11_DATA_LEN +14+2); 352 skb = dev_alloc_skb(IEEE80211_DATA_LEN +14+2);
353 if (!skb) { 353 if (!skb) {
354 kfree(frag); 354 kfree(frag);
355 goto resubmit; 355 goto resubmit;
356 } 356 }
357 frag->skb = skb; 357 frag->skb = skb;
358 frag->seq = seq & IEEE802_11_SCTL_SEQ; 358 frag->seq = seq & IEEE80211_SCTL_SEQ;
359 skb_reserve(skb, 2); 359 skb_reserve(skb, 2);
360 memcpy(skb_put(skb, 12), &data[datalen-14], 12); 360 memcpy(skb_put(skb, 12), &data[datalen-14], 12);
361 memcpy(skb_put(skb, 2), &data[6], 2); 361 memcpy(skb_put(skb, 2), &data[6], 2);
@@ -364,7 +364,7 @@ static void zd1201_usbrx(struct urb *urb, struct pt_regs *regs)
364 goto resubmit; 364 goto resubmit;
365 } 365 }
366 hlist_for_each_entry(frag, node, &zd->fraglist, fnode) 366 hlist_for_each_entry(frag, node, &zd->fraglist, fnode)
367 if(frag->seq == (seq&IEEE802_11_SCTL_SEQ)) 367 if(frag->seq == (seq&IEEE80211_SCTL_SEQ))
368 break; 368 break;
369 if (!frag) 369 if (!frag)
370 goto resubmit; 370 goto resubmit;
@@ -372,7 +372,7 @@ static void zd1201_usbrx(struct urb *urb, struct pt_regs *regs)
372 ptr = skb_put(skb, len); 372 ptr = skb_put(skb, len);
373 if (ptr) 373 if (ptr)
374 memcpy(ptr, data+8, len); 374 memcpy(ptr, data+8, len);
375 if (fc & IEEE802_11_FCTL_MOREFRAGS) 375 if (fc & IEEE80211_FCTL_MOREFRAGS)
376 goto resubmit; 376 goto resubmit;
377 hlist_del_init(&frag->fnode); 377 hlist_del_init(&frag->fnode);
378 kfree(frag); 378 kfree(frag);
diff --git a/drivers/w1/w1_int.c b/drivers/w1/w1_int.c
index b5a5e04b6d37..498ad505fa5f 100644
--- a/drivers/w1/w1_int.c
+++ b/drivers/w1/w1_int.c
@@ -86,9 +86,9 @@ static struct w1_master * w1_alloc_dev(u32 id, int slave_count, int slave_ttl,
86 86
87 dev->driver = driver; 87 dev->driver = driver;
88 88
89 dev->groups = 23; 89 dev->groups = 1;
90 dev->seq = 1; 90 dev->seq = 1;
91 dev->nls = netlink_kernel_create(NETLINK_W1, NULL); 91 dev->nls = netlink_kernel_create(NETLINK_W1, 1, NULL, THIS_MODULE);
92 if (!dev->nls) { 92 if (!dev->nls) {
93 printk(KERN_ERR "Failed to create new netlink socket(%u) for w1 master %s.\n", 93 printk(KERN_ERR "Failed to create new netlink socket(%u) for w1 master %s.\n",
94 NETLINK_NFLOG, dev->dev.bus_id); 94 NETLINK_NFLOG, dev->dev.bus_id);
@@ -225,3 +225,5 @@ void w1_remove_master_device(struct w1_bus_master *bm)
225 225
226EXPORT_SYMBOL(w1_add_master_device); 226EXPORT_SYMBOL(w1_add_master_device);
227EXPORT_SYMBOL(w1_remove_master_device); 227EXPORT_SYMBOL(w1_remove_master_device);
228
229MODULE_ALIAS_NET_PF_PROTO(PF_NETLINK, NETLINK_W1);
diff --git a/drivers/w1/w1_netlink.c b/drivers/w1/w1_netlink.c
index 2a82fb055c70..e7b774423dd6 100644
--- a/drivers/w1/w1_netlink.c
+++ b/drivers/w1/w1_netlink.c
@@ -51,7 +51,7 @@ void w1_netlink_send(struct w1_master *dev, struct w1_netlink_msg *msg)
51 51
52 memcpy(data, msg, sizeof(struct w1_netlink_msg)); 52 memcpy(data, msg, sizeof(struct w1_netlink_msg));
53 53
54 NETLINK_CB(skb).dst_groups = dev->groups; 54 NETLINK_CB(skb).dst_group = dev->groups;
55 netlink_broadcast(dev->nls, skb, 0, dev->groups, GFP_ATOMIC); 55 netlink_broadcast(dev->nls, skb, 0, dev->groups, GFP_ATOMIC);
56 56
57nlmsg_failure: 57nlmsg_failure: