00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036 #include <linux/module.h>
00037
00038 #include <linux/kernel.h>
00039 #include <linux/types.h>
00040 #include <linux/skbuff.h>
00041 #include <linux/netdevice.h>
00042 #include <linux/ioport.h>
00043 #include <linux/delay.h>
00044 #include <linux/malloc.h>
00045 #include <linux/init.h>
00046 #include <linux/rtnetlink.h>
00047 #include <linux/serial_reg.h>
00048
00049 #include <asm/io.h>
00050 #include <asm/dma.h>
00051 #include <asm/byteorder.h>
00052
00053 #ifdef CONFIG_APM
00054 #include <linux/apm_bios.h>
00055 #endif
00056
00057 #include <net/irda/wrapper.h>
00058 #include <net/irda/irda.h>
00059 #include <net/irda/irmod.h>
00060 #include <net/irda/irlap_frame.h>
00061 #include <net/irda/irda_device.h>
00062
00063 #include <net/irda/smc-ircc.h>
00064 #include <net/irda/irport.h>
00065
00066 static char *driver_name = "smc-ircc";
00067
00068 #define CHIP_IO_EXTENT 8
00069
00070 static unsigned int io[] = { ~0, ~0 };
00071 static unsigned int io2[] = { 0, 0 };
00072
00073 static struct ircc_cb *dev_self[] = { NULL, NULL};
00074
00075
00076 static int ircc_open(int i, unsigned int iobase, unsigned int board_addr);
00077 #ifdef MODULE
00078 static int ircc_close(struct ircc_cb *self);
00079 #endif
00080 static int ircc_probe(int iobase, int board_addr);
00081 static int ircc_probe_58(smc_chip_t *chip, chipio_t *info);
00082 static int ircc_probe_69(smc_chip_t *chip, chipio_t *info);
00083 static int ircc_dma_receive(struct ircc_cb *self, int iobase);
00084 static void ircc_dma_receive_complete(struct ircc_cb *self, int iobase);
00085 static int ircc_hard_xmit(struct sk_buff *skb, struct device *dev);
00086 static void ircc_dma_xmit(struct ircc_cb *self, int iobase, int bofs);
00087 static void ircc_change_speed(void *priv, __u32 speed);
00088 static void ircc_interrupt(int irq, void *dev_id, struct pt_regs *regs);
00089 static int ircc_is_receiving(struct ircc_cb *self);
00090
00091 static int ircc_net_open(struct device *dev);
00092 static int ircc_net_close(struct device *dev);
00093 #ifdef CONFIG_APM
00094 static int ircc_apmproc(apm_event_t event);
00095 #endif
00096
00097
00098 static smc_chip_t chips[] =
00099 {
00100 { "FDC37C669", 0x55, 0x55, 0x0d, 0x04, ircc_probe_69 },
00101 { "FDC37N869", 0x55, 0x00, 0x0d, 0x29, ircc_probe_69 },
00102 { "FDC37N958", 0x55, 0x55, 0x20, 0x09, ircc_probe_58 },
00103 { NULL }
00104 };
00105
00106 static int ircc_irq=255;
00107 static int ircc_dma=255;
00108
00109 static inline void register_bank(int iobase, int bank)
00110 {
00111 outb(((inb(iobase+IRCC_MASTER) & 0xf0) | (bank & 0x07)),
00112 iobase+IRCC_MASTER);
00113 }
00114
00115
00116
00117
00118
00119
00120
00121 int __init ircc_init(void)
00122 {
00123 static int smcreg[] = { 0x3f0, 0x370 };
00124 smc_chip_t *chip;
00125 chipio_t info;
00126 int ret = -ENODEV;
00127 int i;
00128
00129 IRDA_DEBUG(0, __FUNCTION__ "\n");
00130
00131
00132 for (chip=chips; chip->name ; chip++,i++) {
00133 for (i=0; i<2; i++) {
00134 info.cfg_base = smcreg[i];
00135
00136
00137
00138
00139
00140
00141 if (io[i] < 2000) {
00142 info.fir_base = io[i];
00143 info.sir_base = io2[i];
00144 } else if (chip->probe(chip, &info) < 0)
00145 continue;
00146 if (check_region(info.fir_base, CHIP_IO_EXTENT) < 0)
00147 continue;
00148 if (check_region(info.sir_base, CHIP_IO_EXTENT) < 0)
00149 continue;
00150 if (ircc_open(i, info.fir_base, info.sir_base) == 0)
00151 ret = 0;
00152 }
00153 }
00154 return ret;
00155 }
00156
00157
00158
00159
00160
00161
00162
00163 #ifdef MODULE
00164 static void ircc_cleanup(void)
00165 {
00166 int i;
00167
00168 IRDA_DEBUG(0, __FUNCTION__ "\n");
00169
00170 for (i=0; i < 2; i++) {
00171 if (dev_self[i])
00172 ircc_close(dev_self[i]);
00173 }
00174 }
00175 #endif
00176
00177
00178
00179
00180
00181
00182
00183 static int ircc_open(int i, unsigned int fir_base, unsigned int sir_base)
00184 {
00185 struct ircc_cb *self;
00186 struct irport_cb *irport;
00187 int config;
00188 int ret;
00189
00190 IRDA_DEBUG(0, __FUNCTION__ "\n");
00191
00192 if ((config = ircc_probe(fir_base, sir_base)) == -1) {
00193 IRDA_DEBUG(0, __FUNCTION__
00194 "(), addr 0x%04x - no device found!\n", fir_base);
00195 return -1;
00196 }
00197
00198
00199
00200
00201 self = kmalloc(sizeof(struct ircc_cb), GFP_KERNEL);
00202 if (self == NULL) {
00203 ERROR("%s, Can't allocate memory for control block!\n",
00204 driver_name);
00205 return -ENOMEM;
00206 }
00207 memset(self, 0, sizeof(struct ircc_cb));
00208 spin_lock_init(&self->lock);
00209
00210
00211 dev_self[i] = self;
00212
00213 irport = irport_open(i, sir_base, config >> 4 & 0x0f);
00214 if (!irport)
00215 return -ENODEV;
00216
00217
00218 self->netdev = irport->netdev;
00219 self->irport = irport;
00220 irport->priv = self;
00221
00222
00223 self->io.fir_base = fir_base;
00224 self->io.sir_base = sir_base;
00225 self->io.irq = config >> 4 & 0x0f;
00226 if (ircc_irq < 255) {
00227 MESSAGE("%s, Overriding IRQ - chip says %d, using %d\n",
00228 driver_name, self->io.irq, ircc_irq);
00229 self->io.irq = ircc_irq;
00230 }
00231 self->io.fir_ext = CHIP_IO_EXTENT;
00232 self->io.sir_ext = 8;
00233 self->io.dma = config & 0x0f;
00234 if (ircc_dma < 255) {
00235 MESSAGE("%s, Overriding DMA - chip says %d, using %d\n",
00236 driver_name, self->io.dma, ircc_dma);
00237 self->io.dma = ircc_dma;
00238 }
00239
00240
00241 ret = check_region(self->io.fir_base, self->io.fir_ext);
00242 if (ret < 0) {
00243 IRDA_DEBUG(0, __FUNCTION__ ": can't get fir_base of 0x%03x\n",
00244 self->io.fir_base);
00245 kfree(self);
00246 return -ENODEV;
00247 }
00248 request_region(self->io.fir_base, self->io.fir_ext, driver_name);
00249
00250
00251 irda_init_max_qos_capabilies(&irport->qos);
00252
00253
00254 irport->qos.baud_rate.bits = IR_9600|IR_19200|IR_38400|IR_57600|
00255 IR_115200|IR_576000|IR_1152000|(IR_4000000 << 8);
00256
00257 irport->qos.min_turn_time.bits = 0x07;
00258 irda_qos_bits_to_value(&irport->qos);
00259
00260 irport->flags = IFF_FIR|IFF_MIR|IFF_SIR|IFF_DMA|IFF_PIO;
00261
00262
00263 self->rx_buff.truesize = 4000;
00264 self->tx_buff.truesize = 4000;
00265
00266 self->rx_buff.head = (__u8 *) kmalloc(self->rx_buff.truesize,
00267 GFP_KERNEL|GFP_DMA);
00268 if (self->rx_buff.head == NULL)
00269 return -ENOMEM;
00270 memset(self->rx_buff.head, 0, self->rx_buff.truesize);
00271
00272 self->tx_buff.head = (__u8 *) kmalloc(self->tx_buff.truesize,
00273 GFP_KERNEL|GFP_DMA);
00274 if (self->tx_buff.head == NULL) {
00275 kfree(self->rx_buff.head);
00276 return -ENOMEM;
00277 }
00278 memset(self->tx_buff.head, 0, self->tx_buff.truesize);
00279
00280 self->rx_buff.in_frame = FALSE;
00281 self->rx_buff.state = OUTSIDE_FRAME;
00282 self->tx_buff.data = self->tx_buff.head;
00283 self->rx_buff.data = self->rx_buff.head;
00284
00285
00286 irport->change_speed = &ircc_change_speed;
00287 irport->interrupt = &ircc_interrupt;
00288 self->netdev->open = &ircc_net_open;
00289 self->netdev->stop = &ircc_net_close;
00290
00291 irport_start(self->irport);
00292
00293 return 0;
00294 }
00295
00296
00297
00298
00299
00300
00301
00302 #ifdef MODULE
00303 static int ircc_close(struct ircc_cb *self)
00304 {
00305 int iobase;
00306
00307 IRDA_DEBUG(0, __FUNCTION__ "\n");
00308
00309 ASSERT(self != NULL, return -1;);
00310
00311 iobase = self->io.fir_base;
00312
00313 irport_close(self->irport);
00314
00315
00316 register_bank(iobase, 0);
00317 outb(0, iobase+IRCC_IER);
00318 outb(IRCC_MASTER_RESET, iobase+IRCC_MASTER);
00319 outb(0x00, iobase+IRCC_MASTER);
00320 #if 0
00321
00322 register_bank(iobase, 1);
00323 outb(IRCC_CFGA_IRDA_SIR_A|IRCC_CFGA_TX_POLARITY, iobase+IRCC_SCE_CFGA);
00324 outb(IRCC_CFGB_IR, iobase+IRCC_SCE_CFGB);
00325 #endif
00326
00327 IRDA_DEBUG(0, __FUNCTION__ "(), releasing 0x%03x\n",
00328 self->io.fir_base);
00329
00330 release_region(self->io.fir_base, self->io.fir_ext);
00331
00332 if (self->tx_buff.head)
00333 kfree(self->tx_buff.head);
00334
00335 if (self->rx_buff.head)
00336 kfree(self->rx_buff.head);
00337
00338 kfree(self);
00339
00340 return 0;
00341 }
00342 #endif
00343
00344
00345
00346
00347
00348
00349
00350 static int ircc_probe_69(smc_chip_t *chip, chipio_t *info)
00351 {
00352 int cfg_base = info->cfg_base;
00353 __u8 devid, mode;
00354 int ret = -ENODEV;
00355 int fir_io;
00356
00357 IRDA_DEBUG(0, __FUNCTION__ "()\n");
00358
00359
00360 outb(chip->entr1, cfg_base);
00361 outb(chip->entr2, cfg_base);
00362
00363 outb(chip->cid_index, cfg_base);
00364 devid = inb(cfg_base+1);
00365 IRDA_DEBUG(0, __FUNCTION__ "(), devid=0x%02x\n",devid);
00366
00367
00368 if (devid == chip->cid_value) {
00369 outb(0x0c, cfg_base);
00370 mode = inb(cfg_base+1);
00371 mode = (mode & 0x38) >> 3;
00372
00373
00374 if (mode && mode < 4) {
00375
00376 outb(0x25, cfg_base);
00377 info->sir_base = inb(cfg_base+1) << 2;
00378
00379
00380 outb(0x2b, cfg_base);
00381 fir_io = inb(cfg_base+1) << 3;
00382 if (fir_io) {
00383 ret = 0;
00384 info->fir_base = fir_io;
00385 }
00386 }
00387 }
00388
00389
00390 outb(0xaa, cfg_base);
00391
00392 return ret;
00393 }
00394
00395
00396
00397
00398
00399
00400
00401 static int ircc_probe_58(smc_chip_t *chip, chipio_t *info)
00402 {
00403 int cfg_base = info->cfg_base;
00404 __u8 devid;
00405 int ret = -ENODEV;
00406 int fir_io;
00407
00408 IRDA_DEBUG(0, __FUNCTION__ "()\n");
00409
00410
00411 outb(chip->entr1, cfg_base);
00412 outb(chip->entr2, cfg_base);
00413
00414 outb(chip->cid_index, cfg_base);
00415 devid = inb(cfg_base+1);
00416 IRDA_DEBUG(0, __FUNCTION__ "(), devid=0x%02x\n",devid);
00417
00418
00419 if (devid == chip->cid_value) {
00420
00421 outb(0x07, cfg_base);
00422 outb(0x05, cfg_base + 1);
00423
00424
00425 outb(0x60, cfg_base);
00426 info->sir_base = inb(cfg_base + 1) << 8;
00427 outb(0x61, cfg_base);
00428 info->sir_base |= inb(cfg_base + 1);
00429
00430
00431 outb(0x62, cfg_base);
00432 fir_io = inb(cfg_base + 1) << 8;
00433 outb(0x63, cfg_base);
00434 fir_io |= inb(cfg_base + 1);
00435 outb(0x2b, cfg_base);
00436 if (fir_io) {
00437 ret = 0;
00438 info->fir_base = fir_io;
00439 }
00440 }
00441
00442
00443 outb(0xaa, cfg_base);
00444
00445 return ret;
00446 }
00447
00448
00449
00450
00451
00452
00453
00454 static int ircc_probe(int fir_base, int sir_base)
00455 {
00456 int low, high, chip, config, dma, irq;
00457 int iobase = fir_base;
00458 int version = 1;
00459
00460 IRDA_DEBUG(0, __FUNCTION__ "\n");
00461
00462 register_bank(iobase, 3);
00463 high = inb(iobase+IRCC_ID_HIGH);
00464 low = inb(iobase+IRCC_ID_LOW);
00465 chip = inb(iobase+IRCC_CHIP_ID);
00466 version = inb(iobase+IRCC_VERSION);
00467 config = inb(iobase+IRCC_INTERFACE);
00468 irq = config >> 4 & 0x0f;
00469 dma = config & 0x0f;
00470
00471 if (high == 0x10 && low == 0xb8 && (chip == 0xf1 || chip == 0xf2)) {
00472 MESSAGE("SMC IrDA Controller found; IrCC version %d.%d, "
00473 "port 0x%03x, dma=%d, irq=%d\n",
00474 chip & 0x0f, version, iobase, dma, irq);
00475 } else
00476 return -ENODEV;
00477
00478
00479 outb(0x00, iobase+IRCC_MASTER);
00480
00481 return config;
00482 }
00483
00484
00485
00486
00487
00488
00489
00490 static void ircc_change_speed(void *priv, __u32 speed)
00491 {
00492 int iobase, ir_mode, ctrl, fast;
00493 struct ircc_cb *self = (struct ircc_cb *) priv;
00494 struct device *dev;
00495
00496 IRDA_DEBUG(0, __FUNCTION__ "\n");
00497
00498 ASSERT(self != NULL, return;);
00499
00500 dev = self->netdev;
00501 iobase = self->io.fir_base;
00502
00503
00504 self->io.speed = speed;
00505
00506 outb(IRCC_MASTER_RESET, iobase+IRCC_MASTER);
00507 outb(0x00, iobase+IRCC_MASTER);
00508
00509 switch (speed) {
00510 case 9600:
00511 case 19200:
00512 case 38400:
00513 case 57600:
00514 case 115200:
00515 ir_mode = IRCC_CFGA_IRDA_SIR_A;
00516 ctrl = 0;
00517 fast = 0;
00518 break;
00519 case 576000:
00520 ir_mode = IRCC_CFGA_IRDA_HDLC;
00521 ctrl = IRCC_CRC;
00522 fast = 0;
00523 IRDA_DEBUG(0, __FUNCTION__ "(), handling baud of 576000\n");
00524 break;
00525 case 1152000:
00526 ir_mode = IRCC_CFGA_IRDA_HDLC;
00527 ctrl = IRCC_1152 | IRCC_CRC;
00528 fast = 0;
00529 IRDA_DEBUG(0, __FUNCTION__ "(), handling baud of 1152000\n");
00530 break;
00531 case 4000000:
00532 ir_mode = IRCC_CFGA_IRDA_4PPM;
00533 ctrl = IRCC_CRC;
00534 fast = IRCC_LCR_A_FAST;
00535 IRDA_DEBUG(0, __FUNCTION__ "(), handling baud of 4000000\n");
00536 break;
00537 default:
00538 IRDA_DEBUG(0, __FUNCTION__ "(), unknown baud rate of %d\n",
00539 speed);
00540 return;
00541 }
00542
00543 register_bank(iobase, 0);
00544 outb(0, iobase+IRCC_IER);
00545 outb(IRCC_MASTER_INT_EN, iobase+IRCC_MASTER);
00546
00547
00548 if (speed > 115200) {
00549 irport_stop(self->irport);
00550
00551
00552 dev->hard_start_xmit = &ircc_hard_xmit;
00553
00554
00555
00556
00557
00558
00559
00560
00561 ircc_dma_receive(self, iobase);
00562 } else {
00563
00564 dev->hard_start_xmit = &irport_hard_xmit;
00565 irport_start(self->irport);
00566
00567 IRDA_DEBUG(0, __FUNCTION__
00568 "(), using irport to change speed to %d\n", speed);
00569 irport_change_speed(self->irport, speed);
00570 }
00571 dev->tbusy = 0;
00572
00573 register_bank(iobase, 1);
00574 outb(((inb(iobase+IRCC_SCE_CFGA) & 0x87) | ir_mode),
00575 iobase+IRCC_SCE_CFGA);
00576
00577 #ifdef SMC_669
00578 outb(((inb(iobase+IRCC_SCE_CFGB) & 0x3f) | IRCC_CFGB_MUX_COM),
00579 iobase+IRCC_SCE_CFGB);
00580 #else
00581 outb(((inb(iobase+IRCC_SCE_CFGB) & 0x3f) | IRCC_CFGB_MUX_IR),
00582 iobase+IRCC_SCE_CFGB);
00583 #endif
00584 (void) inb(iobase+IRCC_FIFO_THRESHOLD);
00585 outb(64, iobase+IRCC_FIFO_THRESHOLD);
00586
00587 register_bank(iobase, 4);
00588 outb((inb(iobase+IRCC_CONTROL) & 0x30) | ctrl, iobase+IRCC_CONTROL);
00589
00590 register_bank(iobase, 0);
00591 outb(fast, iobase+IRCC_LCR_A);
00592 }
00593
00594
00595
00596
00597
00598
00599
00600 static int ircc_hard_xmit(struct sk_buff *skb, struct device *dev)
00601 {
00602 struct irport_cb *irport;
00603 struct ircc_cb *self;
00604 unsigned long flags;
00605 __u32 speed;
00606 int iobase;
00607 int mtt;
00608
00609 irport = (struct irport_cb *) dev->priv;
00610 self = (struct ircc_cb *) irport->priv;
00611 ASSERT(self != NULL, return 0;);
00612
00613 iobase = self->io.fir_base;
00614
00615 spin_lock_irqsave(&self->lock, flags);
00616
00617
00618 if ((speed = irda_get_speed(skb)) != self->io.speed)
00619 self->new_speed = speed;
00620
00621
00622 if (irda_lock((void *) &dev->tbusy) == FALSE)
00623 return -EBUSY;
00624
00625 memcpy(self->tx_buff.head, skb->data, skb->len);
00626
00627 self->tx_buff.len = skb->len;
00628 self->tx_buff.data = self->tx_buff.head;
00629
00630 mtt = irda_get_mtt(skb);
00631 if (mtt) {
00632 int bofs;
00633
00634
00635
00636
00637
00638 bofs = mtt * (self->io.speed / 1000) / 8000;
00639 if (bofs > 4095)
00640 bofs = 4095;
00641
00642 ircc_dma_xmit(self, iobase, bofs);
00643 } else {
00644
00645 ircc_dma_xmit(self, iobase, 0);
00646 }
00647
00648 spin_unlock_irqrestore(&self->lock, flags);
00649 dev_kfree_skb(skb);
00650
00651 return 0;
00652 }
00653
00654
00655
00656
00657
00658
00659
00660 static void ircc_dma_xmit(struct ircc_cb *self, int iobase, int bofs)
00661 {
00662 __u8 ctrl;
00663
00664 IRDA_DEBUG(2, __FUNCTION__ "\n");
00665 #if 0
00666
00667 register_bank(iobase, 0);
00668 outb(0x00, iobase+IRCC_LCR_B);
00669 #endif
00670 register_bank(iobase, 1);
00671 outb(inb(iobase+IRCC_SCE_CFGB) & ~IRCC_CFGB_DMA_ENABLE,
00672 iobase+IRCC_SCE_CFGB);
00673
00674 self->io.direction = IO_XMIT;
00675
00676
00677 register_bank(iobase, 4);
00678 outb(bofs & 0xff, iobase+IRCC_BOF_COUNT_LO);
00679 ctrl = inb(iobase+IRCC_CONTROL) & 0xf0;
00680 outb(ctrl | ((bofs >> 8) & 0x0f), iobase+IRCC_BOF_COUNT_HI);
00681
00682
00683 outb(self->tx_buff.len >> 8, iobase+IRCC_TX_SIZE_HI);
00684 outb(self->tx_buff.len & 0xff, iobase+IRCC_TX_SIZE_LO);
00685
00686
00687 setup_dma(self->io.dma, self->tx_buff.data, self->tx_buff.len,
00688 DMA_TX_MODE);
00689
00690 outb(UART_MCR_OUT2, self->io.sir_base + UART_MCR);
00691
00692 register_bank(iobase, 1);
00693 outb(inb(iobase+IRCC_SCE_CFGB) | IRCC_CFGB_DMA_ENABLE |
00694 IRCC_CFGB_DMA_BURST, iobase+IRCC_SCE_CFGB);
00695
00696
00697 outb(IRCC_MASTER_INT_EN, iobase+IRCC_MASTER);
00698 register_bank(iobase, 0);
00699 outb(IRCC_IER_ACTIVE_FRAME | IRCC_IER_EOM, iobase+IRCC_IER);
00700
00701
00702 outb(IRCC_LCR_B_SCE_TRANSMIT|IRCC_LCR_B_SIP_ENABLE, iobase+IRCC_LCR_B);
00703 }
00704
00705
00706
00707
00708
00709
00710
00711
00712 static void ircc_dma_xmit_complete(struct ircc_cb *self, int iobase)
00713 {
00714 IRDA_DEBUG(2, __FUNCTION__ "\n");
00715 #if 0
00716
00717 register_bank(iobase, 0);
00718 outb(0x00, iobase+IRCC_LCR_B);
00719 #endif
00720 register_bank(self->io.fir_base, 1);
00721 outb(inb(self->io.fir_base+IRCC_SCE_CFGB) & ~IRCC_CFGB_DMA_ENABLE,
00722 self->io.fir_base+IRCC_SCE_CFGB);
00723
00724
00725 register_bank(iobase, 0);
00726 if (inb(iobase+IRCC_LSR) & IRCC_LSR_UNDERRUN) {
00727 self->irport->stats.tx_errors++;
00728 self->irport->stats.tx_fifo_errors++;
00729
00730
00731 register_bank(iobase, 0);
00732 outb(IRCC_MASTER_ERROR_RESET, iobase+IRCC_MASTER);
00733 outb(0x00, iobase+IRCC_MASTER);
00734 } else {
00735 self->irport->stats.tx_packets++;
00736 self->irport->stats.tx_bytes += self->tx_buff.len;
00737 }
00738
00739
00740 if (self->new_speed) {
00741 ircc_change_speed(self, self->new_speed);
00742 self->new_speed = 0;
00743 }
00744
00745
00746 self->netdev->tbusy = 0;
00747
00748
00749 mark_bh(NET_BH);
00750 }
00751
00752
00753
00754
00755
00756
00757
00758
00759 static int ircc_dma_receive(struct ircc_cb *self, int iobase)
00760 {
00761
00762
00763
00764
00765
00766 setup_dma(self->io.dma, self->rx_buff.data, self->rx_buff.truesize,
00767 DMA_RX_MODE);
00768
00769 register_bank(iobase, 4);
00770 outb((2050 >> 8) & 0x0f, iobase+IRCC_RX_SIZE_HI);
00771 outb(2050 & 0xff, iobase+IRCC_RX_SIZE_LO);
00772
00773 self->io.direction = IO_RECV;
00774 self->rx_buff.data = self->rx_buff.head;
00775
00776
00777
00778
00779 register_bank(iobase, 0);
00780 outb(IRCC_LCR_B_SCE_RECEIVE | IRCC_LCR_B_SIP_ENABLE,
00781 iobase+IRCC_LCR_B);
00782
00783
00784 register_bank(iobase, 1);
00785 outb(inb(iobase+IRCC_SCE_CFGB) | IRCC_CFGB_DMA_ENABLE |
00786 IRCC_CFGB_DMA_BURST, iobase+IRCC_SCE_CFGB);
00787
00788 return 0;
00789 }
00790
00791
00792
00793
00794
00795
00796
00797
00798 static void ircc_dma_receive_complete(struct ircc_cb *self, int iobase)
00799 {
00800 unsigned long flags;
00801 struct sk_buff *skb;
00802 int len, msgcnt;
00803
00804 IRDA_DEBUG(2, __FUNCTION__ "\n");
00805 #if 0
00806
00807 register_bank(iobase, 0);
00808 outb(0x00, iobase+IRCC_LCR_B);
00809 #endif
00810 register_bank(iobase, 0);
00811 msgcnt = inb(iobase+IRCC_LCR_B) & 0x08;
00812
00813 IRDA_DEBUG(2, __FUNCTION__ ": dma count = %d\n",
00814 get_dma_residue(self->io.dma));
00815
00816 len = self->rx_buff.truesize - get_dma_residue(self->io.dma);
00817
00818
00819 if (self->io.speed < 4000000)
00820 len -= 2;
00821 else
00822 len -= 4;
00823
00824 if ((len < 2) && (len > 2050)) {
00825 WARNING(__FUNCTION__ "(), bogus len=%d\n", len);
00826 return;
00827 }
00828 IRDA_DEBUG(2, __FUNCTION__ ": msgcnt = %d, len=%d\n", msgcnt, len);
00829
00830 skb = dev_alloc_skb(len+1);
00831 if (!skb) {
00832 WARNING(__FUNCTION__ "(), memory squeeze, dropping frame.\n");
00833 return;
00834 }
00835
00836 skb_reserve(skb, 1);
00837
00838 memcpy(skb_put(skb, len), self->rx_buff.data, len);
00839 self->irport->stats.rx_packets++;
00840 self->irport->stats.rx_bytes += len;
00841
00842 skb->dev = self->netdev;
00843 skb->mac.raw = skb->data;
00844 skb->protocol = htons(ETH_P_IRDA);
00845 netif_rx(skb);
00846 }
00847
00848
00849
00850
00851
00852
00853
00854 static void ircc_interrupt(int irq, void *dev_id, struct pt_regs *regs)
00855 {
00856 struct device *dev = (struct device *) dev_id;
00857 struct irport_cb *irport;
00858 struct ircc_cb *self;
00859 int iobase, iir;
00860
00861 if (dev == NULL) {
00862 printk(KERN_WARNING "%s: irq %d for unknown device.\n",
00863 driver_name, irq);
00864 return;
00865 }
00866 irport = (struct irport_cb *) dev->priv;
00867 ASSERT(irport != NULL, return;);
00868 self = (struct ircc_cb *) irport->priv;
00869 ASSERT(self != NULL, return;);
00870
00871
00872 if (self->io.speed < 576000) {
00873 irport_interrupt(irq, dev_id, regs);
00874 return;
00875 }
00876 iobase = self->io.fir_base;
00877
00878 spin_lock(&self->lock);
00879 dev->interrupt = 1;
00880
00881 register_bank(iobase, 0);
00882 iir = inb(iobase+IRCC_IIR);
00883
00884
00885 outb(0, iobase+IRCC_IER);
00886
00887 IRDA_DEBUG(2, __FUNCTION__ "(), iir = 0x%02x\n", iir);
00888
00889 if (iir & IRCC_IIR_EOM) {
00890 if (self->io.direction == IO_RECV)
00891 ircc_dma_receive_complete(self, iobase);
00892 else
00893 ircc_dma_xmit_complete(self, iobase);
00894
00895 ircc_dma_receive(self, iobase);
00896 }
00897
00898
00899 register_bank(iobase, 0);
00900 outb(IRCC_IER_ACTIVE_FRAME|IRCC_IER_EOM, iobase+IRCC_IER);
00901
00902 dev->interrupt = 0;
00903 spin_unlock(&self->lock);
00904 }
00905
00906
00907
00908
00909
00910
00911
00912 static int ircc_is_receiving(struct ircc_cb *self)
00913 {
00914 int status = FALSE;
00915
00916
00917 IRDA_DEBUG(0, __FUNCTION__ "\n");
00918
00919 ASSERT(self != NULL, return FALSE;);
00920
00921 IRDA_DEBUG(0, __FUNCTION__ ": dma count = %d\n",
00922 get_dma_residue(self->io.dma));
00923
00924 status = (self->rx_buff.state != OUTSIDE_FRAME);
00925
00926 return status;
00927 }
00928
00929
00930
00931
00932
00933
00934
00935 static int ircc_net_open(struct device *dev)
00936 {
00937 struct irport_cb *irport;
00938 struct ircc_cb *self;
00939 int iobase;
00940
00941 IRDA_DEBUG(0, __FUNCTION__ "\n");
00942
00943 ASSERT(dev != NULL, return -1;);
00944 irport = (struct irport_cb *) dev->priv;
00945 self = (struct ircc_cb *) irport->priv;
00946
00947 ASSERT(self != NULL, return 0;);
00948
00949 iobase = self->io.fir_base;
00950
00951 irport_net_open(dev);
00952
00953
00954
00955
00956
00957 if (request_dma(self->io.dma, dev->name)) {
00958 irport_net_close(dev);
00959
00960 return -EAGAIN;
00961 }
00962
00963 MOD_INC_USE_COUNT;
00964
00965 return 0;
00966 }
00967
00968
00969
00970
00971
00972
00973
00974 static int ircc_net_close(struct device *dev)
00975 {
00976 struct irport_cb *irport;
00977 struct ircc_cb *self;
00978 int iobase;
00979
00980 IRDA_DEBUG(0, __FUNCTION__ "\n");
00981
00982 ASSERT(dev != NULL, return -1;);
00983 irport = (struct irport_cb *) dev->priv;
00984 self = (struct ircc_cb *) irport->priv;
00985
00986 ASSERT(self != NULL, return 0;);
00987
00988 iobase = self->io.fir_base;
00989
00990 irport_net_close(dev);
00991
00992 disable_dma(self->io.dma);
00993
00994 free_dma(self->io.dma);
00995
00996 MOD_DEC_USE_COUNT;
00997
00998 return 0;
00999 }
01000
01001 #ifdef CONFIG_APM
01002 static void ircc_suspend(struct ircc_cb *self)
01003 {
01004 int i = 10;
01005
01006 MESSAGE("%s, Suspending\n", driver_name);
01007
01008 if (self->io.suspended)
01009 return;
01010
01011 ircc_net_close(self->netdev);
01012
01013 self->io.suspended = 1;
01014 }
01015
01016 static void ircc_wakeup(struct ircc_cb *self)
01017 {
01018 struct device *dev = self->netdev;
01019 unsigned long flags;
01020
01021 if (!self->io.suspended)
01022 return;
01023
01024 save_flags(flags);
01025 cli();
01026
01027 ircc_net_open(self->netdev);
01028
01029 restore_flags(flags);
01030 MESSAGE("%s, Waking up\n", driver_name);
01031 }
01032
01033 static int ircc_apmproc(apm_event_t event)
01034 {
01035 static int down = 0;
01036 int i;
01037
01038 switch (event) {
01039 case APM_SYS_SUSPEND:
01040 case APM_USER_SUSPEND:
01041 if (!down) {
01042 for (i=0; i<4; i++) {
01043 if (dev_self[i])
01044 ircc_suspend(dev_self[i]);
01045 }
01046 }
01047 down = 1;
01048 break;
01049 case APM_NORMAL_RESUME:
01050 case APM_CRITICAL_RESUME:
01051 if (down) {
01052 for (i=0; i<4; i++) {
01053 if (dev_self[i])
01054 ircc_wakeup(dev_self[i]);
01055 }
01056 }
01057 down = 0;
01058 break;
01059 }
01060 return 0;
01061 }
01062 #endif
01063
01064 #ifdef MODULE
01065 MODULE_AUTHOR("Thomas Davis <tadavis@jps.net>");
01066 MODULE_DESCRIPTION("SMC IrCC controller driver");
01067 MODULE_PARM(ircc_dma, "1i");
01068 MODULE_PARM(ircc_irq, "1i");
01069
01070 int init_module(void)
01071 {
01072 return ircc_init();
01073 }
01074
01075 void cleanup_module(void)
01076 {
01077 ircc_cleanup();
01078 }
01079
01080 #endif