1/* 2 * Driver for ST5481 USB ISDN modem 3 * 4 * Author Frode Isaksen 5 * Copyright 2001 by Frode Isaksen <fisaksen@bewan.com> 6 * 2001 by Kai Germaschewski <kai.germaschewski@gmx.de> 7 * 8 * This software may be used and distributed according to the terms 9 * of the GNU General Public License, incorporated herein by reference. 10 * 11 */ 12 13#ifndef _ST5481_H_ 14#define _ST5481_H_ 15 16 17// USB IDs, the Product Id is in the range 0x4810-0x481F 18 19#define ST_VENDOR_ID 0x0483 20#define ST5481_PRODUCT_ID 0x4810 21#define ST5481_PRODUCT_ID_MASK 0xFFF0 22 23// ST5481 endpoints when using alternative setting 3 (2B+D). 24// To get the endpoint address, OR with 0x80 for IN endpoints. 25 26#define EP_CTRL 0x00U /* Control endpoint */ 27#define EP_INT 0x01U /* Interrupt endpoint */ 28#define EP_B1_OUT 0x02U /* B1 channel out */ 29#define EP_B1_IN 0x03U /* B1 channel in */ 30#define EP_B2_OUT 0x04U /* B2 channel out */ 31#define EP_B2_IN 0x05U /* B2 channel in */ 32#define EP_D_OUT 0x06U /* D channel out */ 33#define EP_D_IN 0x07U /* D channel in */ 34 35// Number of isochronous packets. With 20 packets we get 36// 50 interrupts/sec for each endpoint. 37 38#define NUM_ISO_PACKETS_D 20 39#define NUM_ISO_PACKETS_B 20 40 41// Size of each isochronous packet. 42// In outgoing direction we need to match ISDN data rates: 43// D: 2 bytes / msec -> 16 kbit / s 44// B: 16 bytes / msec -> 64 kbit / s 45#define SIZE_ISO_PACKETS_D_IN 16 46#define SIZE_ISO_PACKETS_D_OUT 2 47#define SIZE_ISO_PACKETS_B_IN 32 48#define SIZE_ISO_PACKETS_B_OUT 8 49 50// If we overrun/underrun, we send one packet with +/- 2 bytes 51#define B_FLOW_ADJUST 2 52 53// Registers that are written using vendor specific device request 54// on endpoint 0. 55 56#define LBA 0x02 /* S loopback */ 57#define SET_DEFAULT 0x06 /* Soft reset */ 58#define LBB 0x1D /* S maintenance loopback */ 59#define STT 0x1e /* S force transmission signals */ 60#define SDA_MIN 0x20 /* SDA-sin minimal value */ 61#define SDA_MAX 0x21 /* SDA-sin maximal value */ 62#define SDELAY_VALUE 0x22 /* Delay between Tx and Rx clock */ 63#define IN_D_COUNTER 0x36 /* D receive channel fifo counter */ 64#define OUT_D_COUNTER 0x37 /* D transmit channel fifo counter */ 65#define IN_B1_COUNTER 0x38 /* B1 receive channel fifo counter */ 66#define OUT_B1_COUNTER 0x39 /* B1 transmit channel fifo counter */ 67#define IN_B2_COUNTER 0x3a /* B2 receive channel fifo counter */ 68#define OUT_B2_COUNTER 0x3b /* B2 transmit channel fifo counter */ 69#define FFCTRL_IN_D 0x3C /* D receive channel fifo threshold low */ 70#define FFCTRH_IN_D 0x3D /* D receive channel fifo threshold high */ 71#define FFCTRL_OUT_D 0x3E /* D transmit channel fifo threshold low */ 72#define FFCTRH_OUT_D 0x3F /* D transmit channel fifo threshold high */ 73#define FFCTRL_IN_B1 0x40 /* B1 receive channel fifo threshold low */ 74#define FFCTRH_IN_B1 0x41 /* B1 receive channel fifo threshold high */ 75#define FFCTRL_OUT_B1 0x42 /* B1 transmit channel fifo threshold low */ 76#define FFCTRH_OUT_B1 0x43 /* B1 transmit channel fifo threshold high */ 77#define FFCTRL_IN_B2 0x44 /* B2 receive channel fifo threshold low */ 78#define FFCTRH_IN_B2 0x45 /* B2 receive channel fifo threshold high */ 79#define FFCTRL_OUT_B2 0x46 /* B2 transmit channel fifo threshold low */ 80#define FFCTRH_OUT_B2 0x47 /* B2 transmit channel fifo threshold high */ 81#define MPMSK 0x4A /* Multi purpose interrupt MASK register */ 82#define FFMSK_D 0x4c /* D fifo interrupt MASK register */ 83#define FFMSK_B1 0x4e /* B1 fifo interrupt MASK register */ 84#define FFMSK_B2 0x50 /* B2 fifo interrupt MASK register */ 85#define GPIO_DIR 0x52 /* GPIO pins direction registers */ 86#define GPIO_OUT 0x53 /* GPIO pins output register */ 87#define GPIO_IN 0x54 /* GPIO pins input register */ 88#define TXCI 0x56 /* CI command to be transmitted */ 89 90 91// Format of the interrupt packet received on endpoint 1: 92// 93// +--------+--------+--------+--------+--------+--------+ 94// !MPINT !FFINT_D !FFINT_B1!FFINT_B2!CCIST !GPIO_INT! 95// +--------+--------+--------+--------+--------+--------+ 96 97// Offsets in the interrupt packet 98 99#define MPINT 0 100#define FFINT_D 1 101#define FFINT_B1 2 102#define FFINT_B2 3 103#define CCIST 4 104#define GPIO_INT 5 105#define INT_PKT_SIZE 6 106 107// MPINT 108#define LSD_INT 0x80 /* S line activity detected */ 109#define RXCI_INT 0x40 /* Indicate primitive arrived */ 110#define DEN_INT 0x20 /* Signal enabling data out of D Tx fifo */ 111#define DCOLL_INT 0x10 /* D channel collision */ 112#define AMIVN_INT 0x04 /* AMI violation number reached 2 */ 113#define INFOI_INT 0x04 /* INFOi changed */ 114#define DRXON_INT 0x02 /* Reception channel active */ 115#define GPCHG_INT 0x01 /* GPIO pin value changed */ 116 117// FFINT_x 118#define IN_OVERRUN 0x80 /* In fifo overrun */ 119#define OUT_UNDERRUN 0x40 /* Out fifo underrun */ 120#define IN_UP 0x20 /* In fifo thresholdh up-crossed */ 121#define IN_DOWN 0x10 /* In fifo thresholdl down-crossed */ 122#define OUT_UP 0x08 /* Out fifo thresholdh up-crossed */ 123#define OUT_DOWN 0x04 /* Out fifo thresholdl down-crossed */ 124#define IN_COUNTER_ZEROED 0x02 /* In down-counter reached 0 */ 125#define OUT_COUNTER_ZEROED 0x01 /* Out down-counter reached 0 */ 126 127#define ANY_REC_INT (IN_OVERRUN+IN_UP+IN_DOWN+IN_COUNTER_ZEROED) 128#define ANY_XMIT_INT (OUT_UNDERRUN+OUT_UP+OUT_DOWN+OUT_COUNTER_ZEROED) 129 130 131// Level 1 commands that are sent using the TXCI device request 132#define ST5481_CMD_DR 0x0 /* Deactivation Request */ 133#define ST5481_CMD_RES 0x1 /* state machine RESet */ 134#define ST5481_CMD_TM1 0x2 /* Test Mode 1 */ 135#define ST5481_CMD_TM2 0x3 /* Test Mode 2 */ 136#define ST5481_CMD_PUP 0x7 /* Power UP */ 137#define ST5481_CMD_AR8 0x8 /* Activation Request class 1 */ 138#define ST5481_CMD_AR10 0x9 /* Activation Request class 2 */ 139#define ST5481_CMD_ARL 0xA /* Activation Request Loopback */ 140#define ST5481_CMD_PDN 0xF /* Power DoWn */ 141 142// Turn on/off the LEDs using the GPIO device request. 143// To use the B LEDs, number_of_leds must be set to 4 144#define B1_LED 0x10U 145#define B2_LED 0x20U 146#define GREEN_LED 0x40U 147#define RED_LED 0x80U 148 149// D channel out states 150enum { 151 ST_DOUT_NONE, 152 153 ST_DOUT_SHORT_INIT, 154 ST_DOUT_SHORT_WAIT_DEN, 155 156 ST_DOUT_LONG_INIT, 157 ST_DOUT_LONG_WAIT_DEN, 158 ST_DOUT_NORMAL, 159 160 ST_DOUT_WAIT_FOR_UNDERRUN, 161 ST_DOUT_WAIT_FOR_NOT_BUSY, 162 ST_DOUT_WAIT_FOR_STOP, 163 ST_DOUT_WAIT_FOR_RESET, 164}; 165 166#define DOUT_STATE_COUNT (ST_DOUT_WAIT_FOR_RESET + 1) 167 168// D channel out events 169enum { 170 EV_DOUT_START_XMIT, 171 EV_DOUT_COMPLETE, 172 EV_DOUT_DEN, 173 EV_DOUT_RESETED, 174 EV_DOUT_STOPPED, 175 EV_DOUT_COLL, 176 EV_DOUT_UNDERRUN, 177}; 178 179#define DOUT_EVENT_COUNT (EV_DOUT_UNDERRUN + 1) 180 181// ---------------------------------------------------------------------- 182 183enum { 184 ST_L1_F3, 185 ST_L1_F4, 186 ST_L1_F6, 187 ST_L1_F7, 188 ST_L1_F8, 189}; 190 191#define L1_STATE_COUNT (ST_L1_F8+1) 192 193// The first 16 entries match the Level 1 indications that 194// are found at offset 4 (CCIST) in the interrupt packet 195 196enum { 197 EV_IND_DP, // 0000 Deactivation Pending 198 EV_IND_1, // 0001 199 EV_IND_2, // 0010 200 EV_IND_3, // 0011 201 EV_IND_RSY, // 0100 ReSYnchronizing 202 EV_IND_5, // 0101 203 EV_IND_6, // 0110 204 EV_IND_7, // 0111 205 EV_IND_AP, // 1000 Activation Pending 206 EV_IND_9, // 1001 207 EV_IND_10, // 1010 208 EV_IND_11, // 1011 209 EV_IND_AI8, // 1100 Activation Indication class 8 210 EV_IND_AI10,// 1101 Activation Indication class 10 211 EV_IND_AIL, // 1110 Activation Indication Loopback 212 EV_IND_DI, // 1111 Deactivation Indication 213 EV_PH_ACTIVATE_REQ, 214 EV_PH_DEACTIVATE_REQ, 215 EV_TIMER3, 216}; 217 218#define L1_EVENT_COUNT (EV_TIMER3 + 1) 219 220#define ERR(format, arg...) \ 221printk(KERN_ERR "%s:%s: " format "\n" , __FILE__, __FUNCTION__ , ## arg) 222 223#define WARN(format, arg...) \ 224printk(KERN_WARNING "%s:%s: " format "\n" , __FILE__, __FUNCTION__ , ## arg) 225 226#define INFO(format, arg...) \ 227printk(KERN_INFO "%s:%s: " format "\n" , __FILE__, __FUNCTION__ , ## arg) 228 229#include "isdnhdlc.h" 230#include "fsm.h" 231#include "hisax_if.h" 232#include <linux/skbuff.h> 233 234/* ====================================================================== 235 * FIFO handling 236 */ 237 238/* Generic FIFO structure */ 239struct fifo { 240 u_char r,w,count,size; 241 spinlock_t lock; 242}; 243 244/* 245 * Init an FIFO 246 */ 247static inline void fifo_init(struct fifo *fifo, int size) 248{ 249 fifo->r = fifo->w = fifo->count = 0; 250 fifo->size = size; 251 spin_lock_init(&fifo->lock); 252} 253 254/* 255 * Add an entry to the FIFO 256 */ 257static inline int fifo_add(struct fifo *fifo) 258{ 259 unsigned long flags; 260 int index; 261 262 if (!fifo) { 263 return -1; 264 } 265 266 spin_lock_irqsave(&fifo->lock, flags); 267 if (fifo->count == fifo->size) { 268 // FIFO full 269 index = -1; 270 } else { 271 // Return index where to get the next data to add to the FIFO 272 index = fifo->w++ & (fifo->size-1); 273 fifo->count++; 274 } 275 spin_unlock_irqrestore(&fifo->lock, flags); 276 return index; 277} 278 279/* 280 * Remove an entry from the FIFO with the index returned. 281 */ 282static inline int fifo_remove(struct fifo *fifo) 283{ 284 unsigned long flags; 285 int index; 286 287 if (!fifo) { 288 return -1; 289 } 290 291 spin_lock_irqsave(&fifo->lock, flags); 292 if (!fifo->count) { 293 // FIFO empty 294 index = -1; 295 } else { 296 // Return index where to get the next data from the FIFO 297 index = fifo->r++ & (fifo->size-1); 298 fifo->count--; 299 } 300 spin_unlock_irqrestore(&fifo->lock, flags); 301 302 return index; 303} 304 305/* ====================================================================== 306 * control pipe 307 */ 308typedef void (*ctrl_complete_t)(void *); 309 310typedef struct ctrl_msg { 311 struct usb_ctrlrequest dr; 312 ctrl_complete_t complete; 313 void *context; 314} ctrl_msg; 315 316/* FIFO of ctrl messages waiting to be sent */ 317#define MAX_EP0_MSG 16 318struct ctrl_msg_fifo { 319 struct fifo f; 320 struct ctrl_msg data[MAX_EP0_MSG]; 321}; 322 323#define MAX_DFRAME_LEN_L1 300 324#define HSCX_BUFMAX 4096 325 326struct st5481_ctrl { 327 struct ctrl_msg_fifo msg_fifo; 328 unsigned long busy; 329 struct urb *urb; 330}; 331 332struct st5481_intr { 333 // struct evt_fifo evt_fifo; 334 struct urb *urb; 335}; 336 337struct st5481_d_out { 338 struct isdnhdlc_vars hdlc_state; 339 struct urb *urb[2]; /* double buffering */ 340 unsigned long busy; 341 struct sk_buff *tx_skb; 342 struct FsmInst fsm; 343}; 344 345struct st5481_b_out { 346 struct isdnhdlc_vars hdlc_state; 347 struct urb *urb[2]; /* double buffering */ 348 u_char flow_event; 349 u_long busy; 350 struct sk_buff *tx_skb; 351}; 352 353struct st5481_in { 354 struct isdnhdlc_vars hdlc_state; 355 struct urb *urb[2]; /* double buffering */ 356 int mode; 357 int bufsize; 358 unsigned int num_packets; 359 unsigned int packet_size; 360 unsigned char ep, counter; 361 unsigned char *rcvbuf; 362 struct st5481_adapter *adapter; 363 struct hisax_if *hisax_if; 364}; 365 366int st5481_setup_in(struct st5481_in *in); 367void st5481_release_in(struct st5481_in *in); 368void st5481_in_mode(struct st5481_in *in, int mode); 369 370struct st5481_bcs { 371 struct hisax_b_if b_if; 372 struct st5481_adapter *adapter; 373 struct st5481_in b_in; 374 struct st5481_b_out b_out; 375 int channel; 376 int mode; 377}; 378 379struct st5481_adapter { 380 struct list_head list; 381 int number_of_leds; 382 struct usb_device *usb_dev; 383 struct hisax_d_if hisax_d_if; 384 385 struct st5481_ctrl ctrl; 386 struct st5481_intr intr; 387 struct st5481_in d_in; 388 struct st5481_d_out d_out; 389 390 unsigned char leds; 391 unsigned int led_counter; 392 393 unsigned long event; 394 395 struct FsmInst l1m; 396 struct FsmTimer timer; 397 398 struct st5481_bcs bcs[2]; 399}; 400 401#define TIMER3_VALUE 7000 402 403/* ====================================================================== 404 * 405 */ 406 407/* 408 * Submit an URB with error reporting. This is a macro so 409 * the __FUNCTION__ returns the caller function name. 410 */ 411#define SUBMIT_URB(urb, mem_flags) \ 412({ \ 413 int status; \ 414 if ((status = usb_submit_urb(urb, mem_flags)) < 0) { \ 415 WARN("usb_submit_urb failed,status=%d", status); \ 416 } \ 417 status; \ 418}) 419 420/* 421 * USB double buffering, return the URB index (0 or 1). 422 */ 423static inline int get_buf_nr(struct urb *urbs[], struct urb *urb) 424{ 425 return (urbs[0]==urb ? 0 : 1); 426} 427 428/* ---------------------------------------------------------------------- */ 429 430/* B Channel */ 431 432int st5481_setup_b(struct st5481_bcs *bcs); 433void st5481_release_b(struct st5481_bcs *bcs); 434void st5481_d_l2l1(struct hisax_if *hisax_d_if, int pr, void *arg); 435 436/* D Channel */ 437 438int st5481_setup_d(struct st5481_adapter *adapter); 439void st5481_release_d(struct st5481_adapter *adapter); 440void st5481_b_l2l1(struct hisax_if *b_if, int pr, void *arg); 441int st5481_d_init(void); 442void st5481_d_exit(void); 443 444/* USB */ 445void st5481_ph_command(struct st5481_adapter *adapter, unsigned int command); 446int st5481_setup_isocpipes(struct urb* urb[2], struct usb_device *dev, 447 unsigned int pipe, int num_packets, 448 int packet_size, int buf_size, 449 usb_complete_t complete, void *context); 450void st5481_release_isocpipes(struct urb* urb[2]); 451 452void st5481_usb_pipe_reset(struct st5481_adapter *adapter, 453 u_char pipe, ctrl_complete_t complete, void *context); 454void st5481_usb_device_ctrl_msg(struct st5481_adapter *adapter, 455 u8 request, u16 value, 456 ctrl_complete_t complete, void *context); 457int st5481_setup_usb(struct st5481_adapter *adapter); 458void st5481_release_usb(struct st5481_adapter *adapter); 459void st5481_start(struct st5481_adapter *adapter); 460void st5481_stop(struct st5481_adapter *adapter); 461 462// ---------------------------------------------------------------------- 463// debugging macros 464 465#define __debug_variable st5481_debug 466#include "hisax_debug.h" 467 468extern int st5481_debug; 469 470#ifdef CONFIG_HISAX_DEBUG 471 472#define DBG_ISO_PACKET(level,urb) \ 473 if (level & __debug_variable) dump_iso_packet(__FUNCTION__,urb) 474 475static void __attribute__((unused)) 476dump_iso_packet(const char *name, struct urb *urb) 477{ 478 int i,j; 479 int len,ofs; 480 u_char *data; 481 482 printk(KERN_DEBUG "%s: packets=%d,errors=%d\n", 483 name,urb->number_of_packets,urb->error_count); 484 for (i = 0; i < urb->number_of_packets; ++i) { 485 if (urb->pipe & USB_DIR_IN) { 486 len = urb->iso_frame_desc[i].actual_length; 487 } else { 488 len = urb->iso_frame_desc[i].length; 489 } 490 ofs = urb->iso_frame_desc[i].offset; 491 printk(KERN_DEBUG "len=%.2d,ofs=%.3d ",len,ofs); 492 if (len) { 493 data = urb->transfer_buffer+ofs; 494 for (j=0; j < len; j++) { 495 printk ("%.2x", data[j]); 496 } 497 } 498 printk("\n"); 499 } 500} 501 502static inline const char *ST5481_CMD_string(int evt) 503{ 504 static char s[16]; 505 506 switch (evt) { 507 case ST5481_CMD_DR: return "DR"; 508 case ST5481_CMD_RES: return "RES"; 509 case ST5481_CMD_TM1: return "TM1"; 510 case ST5481_CMD_TM2: return "TM2"; 511 case ST5481_CMD_PUP: return "PUP"; 512 case ST5481_CMD_AR8: return "AR8"; 513 case ST5481_CMD_AR10: return "AR10"; 514 case ST5481_CMD_ARL: return "ARL"; 515 case ST5481_CMD_PDN: return "PDN"; 516 }; 517 518 sprintf(s,"0x%x",evt); 519 return s; 520} 521 522#else 523 524#define DBG_ISO_PACKET(level,urb) do {} while (0) 525 526#endif 527 528 529 530#endif 531